Authenticating a custom user in Django 1.5

心不动则不痛 提交于 2019-12-24 03:25:54

问题


I have a custom user in a Django 1.5 project, which uses the email field as the username:

class MyUser(AbstractUser):
    my_custom_field = models.CharField(max_length=20, blank=True, null=True)

    USERNAME_FIELD = 'email'

MyUser._meta.get_field_by_name('email')[0]._unique = True
MyUser.REQUIRED_FIELDS.remove('email')

If I try to authenticate that user like so:

auth_user = authenticate(username=email, password=password)
login(request, auth_user)

I get this:

Traceback:
File "/Users/user/dev/proj/app/core/views.py" in post
  39.             login(request, auth_user)
File "/Users/user/.virtualenvs/proj/lib/python2.7/site-packages/django/contrib/auth/__init__.py" in login
  92.     request.session[BACKEND_SESSION_KEY] = user.backend
File "/Users/user/.virtualenvs/proj/lib/python2.7/site-packages/django/utils/functional.py" in inner
  203.         return func(self._wrapped, *args)

Exception Type: AttributeError at /signup
Exception Value: 'AnonymousUser' object has no attribute 'backend'

How am I supposed to authenticate a custom user?


回答1:


My custom model didn't implement create_user() in its apparently-required custom manager.

Here's the full working code:

from django.contrib.auth.models import AbstractUser, BaseUserManager

class MyUserManager(BaseUserManager):
    def create_user(self, email, password=None):
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=MyUserManager.normalize_email(email),
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password):
        user = self.create_user(email,
            password=password,
        )
        user.is_admin = True
        user.save(using=self._db)
        return user


class MyUser(AbstractUser):
    some_custom_field = models.CharField(max_length=20, blank=True, null=True)

    objects = MyUserManager()

    USERNAME_FIELD = 'email'

MyUser._meta.get_field_by_name('email')[0]._unique = True
MyUser.REQUIRED_FIELDS.remove('email')

Django 1.5 "custom user" implementation is an abomination.




回答2:


What Django documentation is saying is

If you’re entirely happy with Django’s User model and you just want to add some additional profile information, you can simply subclass django.contrib.auth.models.AbstractUser and add your custom profile fields

So the idea of AbstractUser is to use it only when you need to add a few additional fields to the user model without creating a separate db table like it was pre Django 1.5.

But when you need a different functionality (like using the email as username,which probably means you won't need the username field) the better approach is the extend the AbstractBaseUser class and set all the fields you need there. This way setting the USERNAME_FIELD='email' will work without writing custom create_user() method.



来源:https://stackoverflow.com/questions/16689056/authenticating-a-custom-user-in-django-1-5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!