2

我在 Django 1.5 项目中有一个自定义用户,它使用该email字段作为用户名:

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')

如果我尝试像这样验证该用户:

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

我明白了:

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'

我应该如何验证自定义用户?

4

2 回答 2

4

我的自定义模型没有create_user()在其显然需要的自定义管理器中实现。

这是完整的工作代码:

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“自定义用户”实现令人厌恶。

于 2013-05-22T11:15:03.390 回答
1

Django 文档说的是

如果您对 Django 的 User 模型完全满意并且只想添加一些额外的配置文件信息,您可以简单地继承 django.contrib.auth.models.AbstractUser 并添加您的自定义配置文件字段

因此 AbstractUser 的想法是仅在您需要向用户模型添加一些附加字段时才使用它,而无需像 Django 1.5 之前那样创建单独的数据库表。

但是当您需要不同的功能时(例如使用电子邮件作为用户名,这可能意味着您不需要用户名字段)更好的方法是扩展 AbstractBaseUser 类并在那里设置您需要的所有字段。这种方式设置USERNAME_FIELD='email'将在不编写自定义 create_user() 方法的情况下工作。

于 2013-05-23T09:21:48.167 回答