Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django AttributeError: 'str' object has no attribute '_default_manager'

The following error seems to occur randomly on my live server (i.e. through apache mod_wsgi) but never in development (i.e. localhost python manage.py runserver).

Note this happens infrequently and is not something that can be reproduced easily or each time a specific url is accessed.

I have seen various answers posted both here on SO and on google but there does not seem to be any definitive reason as to why this error occurs. Maybe this is because the error is fairly generic but the most common answer seems to be due to circular import errors. Another answer I've seen is that model FK field references have not been the correct case (e.g. applabel.model instead of applabel.Model) but all my model FK fields are correct.

The cause of the error seems to point to one of my admin.py files. This file did originally import custom form classes from a forms.py file. Both the admin.py file and forms.py file imported the same models from a models.py file. Therefore I moved the form classes to the admin.py file in case there was a circular reference occurring here but I still occasionally get these errors.

Could anyone shed any light as to why this error occurs and why so randomly? I always ensure the relevant services are restarted after a code update.

Traceback is:

Traceback (most recent call last):

File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 101, in get_response
request.path_info)

File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py", line 250, in resolve
for pattern in self.url_patterns:

File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py", line 279, in _get_url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)

File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py", line 274, in _get_urlconf_module
self._urlconf_module = import_module(self.urlconf_name)

File "/usr/local/lib/python2.7/dist-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)

File "/myproject/urls.py", line 6, in <module>
admin.autodiscover()

File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/__init__.py", line 26, in autodiscover
import_module('%s.admin' % app)

File "/usr/local/lib/python2.7/dist-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)

File "/myproject/myapps/app/admin.py", line 61, in <module>
class CardAdminForm(forms.ModelForm):

File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py", line 205, in __new__
opts.exclude, opts.widgets, formfield_callback)

File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py", line 159, in fields_for_model
formfield = f.formfield(**kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/related.py", line 913, in formfield
'queryset': self.rel.to._default_manager.using(db).complex_filter(self.rel.limit_choices_to),

AttributeError: 'str' object has no attribute '_default_manager'

Packages and versions

  • Warning: cannot find svn location for pymssql==2.0.0b1-dev-20111019
  • Warning: cannot find svn location for distribute==0.6.24dev-r0
  • Django==1.3.3
  • GnuPGInterface==0.3.2
  • Landscape-Client==12.05
  • PAM==0.4.2
  • PIL==1.1.7
  • Twisted-Core==11.1.0
  • apt-xapian-index==0.44
  • argparse==1.2.1
  • chardet==2.0.1
  • command-not-found==0.2.44
  • ## FIXME: could not find svn URL in dependency_links for this package: distribute==0.6.24dev-r0
  • django-debug-toolbar==0.9.4
  • django-rosetta==0.6.8
  • httplib2==0.7.2
  • iotop==0.4.4
  • keyring==0.7.1
  • language-selector==0.1
  • launchpadlib==1.9.12
  • lazr.restfulclient==0.12.0
  • lazr.uri==1.0.3
  • mercurial==2.0.2
  • oauth==1.0.1
  • psycopg2==2.4.5
  • pyOpenSSL==0.12
  • pycrypto==2.4.1
  • ## FIXME: could not find svn URL in dependency_links for this package:pymssql==2.0.0b1-dev-20111019
  • pyserial==2.5
  • python-apt==0.8.3ubuntu7
  • python-debian==0.1.21ubuntu1
  • reportlab==2.5
  • simplejson==2.3.2
  • ufw==0.31.1-1
  • wadllib==1.3.0
  • wsgiref==0.1.2
  • xlwt==0.7.4
  • zope.interface==3.6.1

Database: Postgresql 9.1.5

CardAdmin and CardAdminForm:

class CardAdmin(admin.ModelAdmin):
    form = CardAdminForm
    raw_id_fields = ('cust', 'acc', 'vehicle', 'driver')
    list_display = ('id', 'pan', 'name', 'expiry', 'created', 'modified')
    list_filter = ('status', )
    search_fields = ['id', 'pan']
admin.site.register(Card, CardAdmin)

class CardAdminForm(forms.ModelForm):
    """
    A Form for Cards (Admin console)
    """

    def __init__(self, *args, **kwargs):
        super(CardAdminForm, self).__init__(*args, **kwargs)
        self.fields['cust'].required = True
        self.fields['acc'].required = True
        self.fields['name'].required = True
        self.fields['code'].widget = forms.PasswordInput()
        self.fields['code'].max_length = 6

    class Meta:
        model = Card
        fields = (
            'cust',
            'name',
            'acc',
            'no',
            'code',
            'type',
            'status',
            'address_1',
            'address_2',
            'zip',
            'city',
            'country',
            'phone_no',
            'expiry',
            'vehicle',
            'driver'
        )

    def save(self, commit=True):
        # Save some additional data.
        form_instance = super(CardAdminForm, self).save(commit=False)

        cleaned_data = self.cleaned_data
        form_instance.pan = '%s%s%s'\
        % (
            cleaned_data['acc'].iso.number,
            cleaned_data['acc'].number,
            cleaned_data['no']
        )

        if commit:
            form_instance.save()
        return form_instance
like image 603
chewynougat Avatar asked Sep 17 '12 11:09

chewynougat


3 Answers

Quick note for people still finding this old issue: This case can also be caused by a ForeignKey/ManyToMany/OnetoOne that uses a string as reference that is invalid (eg: not correctly pointing to a model).

I was updating/refactoring a project and ran into this. Turned out it was just a typo.

Kinda weird django doesn't notify clearly it cannot resolve the string, could be because other apps confused it.

like image 189
Bartvds Avatar answered Nov 14 '22 00:11

Bartvds


_default_manager is the attribute on a model that holds the (surprise, surprise) default manager for that model. Django uses this all over the place, especially in the admin, to return querysets for ModelAdmins.

So the error is telling you that somewhere, you've passed a string where a model class or instance was expected. It tries to call _default_manager on the string, and fails, obviously.

However, since the error comes in Django code, in particular when referencing self.rel.to on an instance, I can only assume that you or some third-party whose code you are utilizing has made some pretty integral and monumental changes to something. This is not how the stock code should behave.

like image 9
Chris Pratt Avatar answered Nov 13 '22 23:11

Chris Pratt


The solution to my problem seems to have been resolved by looking at the following links:

Getting the “str” has no property “_default_manager” on a Django app just on startup

and:

Django Ticket 10405 Comment 11

Technically Chris Pratt's answer is absolutely correct and a very good explanation but nowhere in my code could I find an instance that would be causing this error.

The error occurred randomly but the source of this error was mostly being triggered by a server monitoring system requesting the base url (/) for my website (i.e. full HTTP page request). I can only assume the monitoring system uses something like the wget command to make this check so I used this command to test the base url for my website.

Occasionally this command would return a 200 OK response but on most occasions this would return a 500 Internal Server Error response, even though I could access the website fine from a browser. It seems also that a 500 Internal Server Error response would always occur immediately after restarting Apache.

I'm still a bit puzzled as to the exact cause and randomness of this error, discussions I've seen point to a possible bug in the Django framework but this doesn't happen in other websites using the same set up I have implemented here. Reading through the comments in the 2nd link above, it seems to be that a similar code layout has been used as that in my question above (only happens in production using Apache/mod_wsgi, ModelForms used for admin section, using quoted FK references in models).

As mentioned in the above links the solution is to insert:

from django.db.models.loading import cache as model_cache
if not model_cache.loaded:
    model_cache.get_models() 

before:

admin.autodiscover()

in the base urls.py file.

Hope this helps others that may stumble upon this weird issue. I've had no errors since making the above code addition.

like image 6
chewynougat Avatar answered Nov 14 '22 00:11

chewynougat