nickbusted
nickbusted

Reputation: 1109

Default Manager in Django

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

Answers (2)

knbk
knbk

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

ruddra
ruddra

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

Related Questions