Reputation: 1109
When I do not define any managers, I get no errors. However, when I do the following:
class User(AbstractUser):
# some fields
objects = model.Manager()
hstore_manager = hstore.HStoreManager()
I get
AttributeError at'Manager' object has no attribute 'get_by_natural_key'
There is something wrong with /django/contrib/auth/backends.py in authenticate method on this line:
user = UserModel._default_manager.get_by_natural_key(username)
Note that User is inherited from AbstractUser model. Thanks!
Upvotes: 1
Views: 5228
Reputation: 53649
The authentication framework expects that the default manager on your User
object implements some extra methods. The basic methods are implemented in django.contrib.auth.models.BaseUserManager
, the model-specific methods are implemented in django.contrib.auth.models.UserManager
. If your user model is similar to the default implementation (that is, it defines the username
, email
, is_staff
, is_active
, is_superuser
, last_login
, and date_joined
fields), you can just use the UserManager
. Otherwise, you'll have to create a subclass of BaseUserManager
, and implement the create_user
and create_superuser
methods.
As you are using AbstractUser
as a base class, you can use the UserManager
class, or if you need to define any additional methods, a subclass of UserManager
.
Also read the documentation on custom user managers.
Upvotes: 3
Reputation: 51948
Well, if you directly subclass from AbstructUser, you get this error. If you make one to one relation with user, then you will not get this error. For example:
class ExManager(models.Manager):
def get_queryset(self):
return super(ExManager, self).get_queryset().all()
class Post(models.Model):
user= models.OneToOneField(User)
title= models.CharField(max_length=150, null=True, default=None)
objects=models.Manager()
ab_ob= ExManager()
and in django shell I have tested:
In [2]: k=Post.ab_ob.all()
In [3]: k
Out[3]: []
In [4]: from django.contrib.auth.models import User
In [5]: u=User.objects.get(id=1)
In [6]: k1=Post(user=u, title="asdasd")
In [7]: k1.save()
In [8]: k2=Post.ab_ob.all()
In [9]: k2
Out[9]: [<Post: Post object>]
Upvotes: 2