Django AttributeError: 'str' object has no attribute '_default_manager'
Asked Answered
F

7

7

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
Fast answered 17/9, 2012 at 11:31 Comment(3)
Can You write packages versions are You using ? 'pip --freeze' can do that and please write me Database Engine and Version. Contents on 'settings.py' would be nice also. Definition of CardAdmin and CardAdminForm classes are needed alsoCorvese
I think I've edited to include all you require. What settings.py detail do you need? Thanks.Fast
"/myproject/myapps/app/admin.py", line 61 pointing to.. ?Corvese
F
6

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.

Fast answered 20/9, 2012 at 14:54 Comment(1)
In 2023 / Django 4.x ModuleNotFoundError: No module named 'django.db.models.loading' just FYIUnable
A
43

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.

Anglicanism answered 8/1, 2016 at 15:9 Comment(2)
Bumped into the same :)Supercilious
Thanks! Just moved my models into another package (app) and forgot to change to="" parameter.Kao
F
9

_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.

Folk answered 17/9, 2012 at 14:30 Comment(0)
F
6

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.

Fast answered 20/9, 2012 at 14:54 Comment(1)
In 2023 / Django 4.x ModuleNotFoundError: No module named 'django.db.models.loading' just FYIUnable
J
3

I ran in to this error message because I did not correctly specify the model in the meta class of a factory

class FooBarFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = 'foobar'  # <-- must be 'myapp.foobar'
Judsonjudus answered 25/5, 2017 at 10:42 Comment(0)
D
2
File "/home/lb/.local/lib/python3.6/site-packages/django/db/models/fields/related.py", line 1673, in formfield
    'queryset': self.remote_field.model._default_manager.using(using),
AttributeError: 'str' object has no attribute '_default_manager'

In my module there was an incorrect code with a String:

Error:

tags = models.ManyToManyField('Tag', blank=True)

Correct:

tags = models.ManyToManyField(Tag, blank=True)

I have not created the class Tag

Dynamotor answered 29/12, 2021 at 17:33 Comment(0)
B
1

I got a similar error when I did:

from people.models import Quote

    quote = models.ManyToManyField(
            "Quote",
            blank=True,
            verbose_name=_("Quotes"),
            help_text=_("Select quotes"),
            default=None,
            related_name="people_quotes"
        )

But when I removed the quotes around the referenced model "Quote", the error went away.

from people.models import Quote

    quote = models.ManyToManyField(
            Quote,
            blank=True,
            verbose_name=_("Quotes"),
            help_text=_("Select quotes"),
            default=None,
            related_name="people_quotes"
        )
Boscage answered 24/7, 2016 at 1:53 Comment(0)
G
0

Adding to the valid answers, please note that this can happen too when you refer to model in your view as a string.

Example:

class JobDetailView(DetailView):
    model = "Job"
    template_name = "job_details.html"

Here my mistake was to mention the model as string.

Groggy answered 23/5 at 13:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.