Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#19596 closed Bug (fixed)

Django admin should use "_default_manager" not "objects" on csutom auth model class.

Reported by: anonymous Owned by: nobody
Component: contrib.auth Version: 1.5-beta-1
Severity: Release blocker Keywords: auth, objects
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

My case:

I created custom users model "MyUser" and set it as auth model in settings file.

class MyUser(MyAbstractBaseModel, AbstractBaseUser, PermissionsMixin):

...
my_objects = UserManager()

After login to Admin Panel I've got an error: "type object 'MyUser' has no attribute 'objects'"

Moreover "_default_manager" is pointing to "UserManager" in MyAbstractBaseModel. So, in my opinion Admin Panel should use _default_manager, not "objects".

Regards.

Attachments (1)

ticket19596.diff (14.5 KB) - added by apollo13 3 years ago.

Download all attachments as: .zip

Change History (9)

comment:1 Changed 3 years ago by kmtracey

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Severity changed from Normal to Release blocker
  • Triage Stage changed from Unreviewed to Accepted
  • Type changed from Uncategorized to Bug

This report is lacking a traceback, which makes it hard to identify where the problem is exactly. Grepping admin code for ".objects" does not show any hits, so I believe admin is correctly using _default_manager rather than objects. Grepping auth code, however, does show many places where UserModel.objects is used, where UserModel is the model returned from get_user_model() and that seems wrong to me. Shouldn't any auth code which is dealing with a potentially customized User model be using _default_manager rather than objects?

comment:2 Changed 3 years ago by apollo13

For testing purposes I did put a custom usermodel into test_sqlite and got:

PYTHONPATH=.. ./runtests.py --settings=test_sqlite --failfast
Creating test database for alias 'default'...
Traceback (most recent call last):
  File "./runtests.py", line 323, in <module>
    options.failfast, args)
  File "./runtests.py", line 166, in django_tests
    failures = test_runner.run_tests(test_labels, extra_tests=extra_tests)
  File "/home/florian/sources/django.git2/django/test/simple.py", line 368, in run_tests
    old_config = self.setup_databases()
  File "/home/florian/sources/django.git2/django/test/simple.py", line 316, in setup_databases
    self.verbosity, autoclobber=not self.interactive)
  File "/home/florian/sources/django.git2/django/db/backends/creation.py", line 294, in create_test_db
    load_initial_data=False)
  File "/home/florian/sources/django.git2/django/core/management/__init__.py", line 161, in call_command
    return klass.execute(*args, **defaults)
  File "/home/florian/sources/django.git2/django/core/management/base.py", line 251, in execute
    self.validate()
  File "/home/florian/sources/django.git2/django/core/management/base.py", line 281, in validate
    raise CommandError("One or more models did not validate:\n%s" % error_text)
django.core.management.base.CommandError: One or more models did not validate:
m2m_through_regress.usermembership: 'user' defines a relation with the model 'auth.User', which has been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.
m2m_through_regress.group: 'user_members' defines a relation with the model 'auth.User', which has been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.
auth.user: Model has been swapped out for 'auth.CustomExtensionUser' which has not been installed or is abstract.
multiple_database.userprofile: 'user' defines a relation with the model 'auth.User', which has been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.
comments.comment: 'user' has a relation with model auth.CustomExtensionUser, which has either not been installed or is abstract.
comments.commentflag: 'user' has a relation with model auth.CustomExtensionUser, which has either not been installed or is abstract.
modeladmin.validationtestmodel: 'users' defines a relation with the model 'auth.User', which has been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.
admin.logentry: 'user' has a relation with model auth.CustomExtensionUser, which has either not been installed or is abstract.
admin_widgets.car: 'owner' defines a relation with the model 'auth.User', which has been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.
m2m_regress.user: 'friends' defines a relation with the model 'auth.User', which has been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.
admin_views.album: 'owner' defines a relation with the model 'auth.User', which has been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.
extra_regress.order: 'created_by' defines a relation with the model 'auth.User', which has been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.
admin_filters.book: 'author' defines a relation with the model 'auth.User', which has been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.
admin_filters.book: 'contributors' defines a relation with the model 'auth.User', which has been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.
fixtures_regress.stuff: 'owner' defines a relation with the model 'auth.User', which has been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.

Do we want to support that?

comment:3 Changed 3 years ago by apollo13

Ok, running contrib tests with the custom user model from auth fails like this:

admin.logentry: 'user' has a relation with model auth.ExtensionUser, which has either not been installed or is abstract.
auth.user: Model has been swapped out for 'auth.ExtensionUser' which has not been installed or is abstract.
comments.comment: 'user' has a relation with model auth.ExtensionUser, which has either not been installed or is abstract.
comments.commentflag: 'user' has a relation with model auth.ExtensionUser, which has either not been installed or is abstract.

This is to be expected since auth.ExtensionUser is only available inside the auth tests. In a normal manage.py test run this shouldn't cause problems since your custom User will be in INSTALLED_APPS.

Attaching a patch to fix the auth errors.

Changed 3 years ago by apollo13

comment:4 Changed 3 years ago by apollo13

  • Has patch set

comment:5 Changed 3 years ago by akaariai

  • Triage Stage changed from Accepted to Ready for checkin

I have applied & tested the patch in stable/1.5.x. The changes seem fine and all tests pass.

I tried what happens if you change the default User's manager name. The result is that there are some tests failing but all of them are protected by "skip if custom user" decorator.

So, looks ready for commit to me.

comment:6 Changed 3 years ago by Florian Apolloner <florian@…>

  • Resolution set to fixed
  • Status changed from new to closed

In cc4de61a2b36abf418d6f4c720d9e62c405e0612:

Fixed #19596 -- Use _default_manager instead of objects in the auth app.

This is needed to support custom user models which don't define a manager
named objects.

comment:7 Changed 3 years ago by Florian Apolloner <florian@…>

In 5f3c45f7458825b5ca88fb60e5349762fb74d5ae:

[1.5.X] Fixed #19596 -- Use _default_manager instead of objects in the auth app.

This is needed to support custom user models which don't define a manager
named objects.

Backport of cc4de61a2b36abf418d6f4c720d9e62c405e0612 from master.

comment:8 Changed 3 years ago by Florian Apolloner <florian@…>

In 5f3c45f7458825b5ca88fb60e5349762fb74d5ae:

[1.5.X] Fixed #19596 -- Use _default_manager instead of objects in the auth app.

This is needed to support custom user models which don't define a manager
named objects.

Backport of cc4de61a2b36abf418d6f4c720d9e62c405e0612 from master.

Note: See TracTickets for help on using tickets.
Back to Top