首页 文章

在Django 1.5中将电子邮件设置为用户名

提问于
浏览
5

我正在阅读文档:https://docs.djangoproject.com/en/1.5/topics/auth/customizing/#substituting-a-custom-user-model

所以在我的settings.py中,我把:

AUTH_USER_MODEL = 'membership.User'

在我的会员应用程序models.py我有这个:

from django.contrib.auth.models import AbstractBaseUser

class User(AbstractBaseUser):
    USERNAME_FIELD = 'email'

运行python manage.py syncdb给了我:

FieldDoesNotExist: User has no field named 'email'

我检查了AbstractBaseUser类的源代码,当然也定义了该字段,如下所示:https://github.com/django/django/blob/master/django/contrib/auth/models.py#L359

怎么了?

2 回答

  • 18

    AbstractBaseUser 没有电子邮件字段, AbstractUser .

    如果要将电子邮件用作唯一标识符,则需要从AbstractBaseUser创建子类并使用 unique=True 定义电子邮件字段,并编写其他功能,例如模型的 Manager

    from django.contrib.auth.models import AbstractBaseUser, BaseUserManager,\
        PermissionsMixin
    from django.db import models
    from django.utils.translation import ugettext_lazy as _
    from django.utils import timezone
    from django.utils.http import urlquote
    
    
    class CustomUserManager(BaseUserManager):
    
        def create_user(self, email, password=None, **extra_fields):
            """
            Creates and saves a User with the given email and password.
            """
            now = timezone.now()
            if not email:
                raise ValueError('The given email must be set')
            email = CustomUserManager.normalize_email(email)
            user = self.model(email=email,
                              is_staff=False, is_active=True, is_superuser=False,
                              last_login=now, date_joined=now, **extra_fields)
    
            user.set_password(password)
            user.save(using=self._db)
            return user
    
        def create_superuser(self, email, password, **extra_fields):
            u = self.create_user(email, password, **extra_fields)
            u.is_staff = True
            u.is_active = True
            u.is_superuser = True
            u.save(using=self._db)
            return u
    
    
    class User(AbstractBaseUser, PermissionsMixin):
        email = models.EmailField(_('email address'), unique=True)
        first_name = models.CharField(_('first name'), max_length=30, blank=True)
        last_name = models.CharField(_('last name'), max_length=30, blank=True)
        is_staff = models.BooleanField(_('staff status'), default=False,
            help_text=_('Designates whether the user can log into this admin '
                        'site.'))
        is_active = models.BooleanField(_('active'), default=True,
            help_text=_('Designates whether this user should be treated as '
                        'active. Unselect this instead of deleting accounts.'))
        date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
    
        objects = CustomUserManager()
    
        USERNAME_FIELD = 'email'
    
        class Meta:
            verbose_name = _('user')
            verbose_name_plural = _('users')
    
        def get_absolute_url(self):
            return "/users/%s/" % urlquote(self.pk)
    
        def get_full_name(self):
            """
            Returns the first_name plus the last_name, with a space in between.
            """
            full_name = '%s %s' % (self.first_name, self.last_name)
            return full_name.strip()
    
        def get_short_name(self):
            "Returns the short name for the user."
            return self.first_name
    
        # define here other needed methods
        # Look at django.contrib.auth.models.AbstractUser
    

    此外,您可能希望将此用户添加到管理页面 . 查看UserAdmin并重新定义它以与使用电子邮件字段作为唯一标识符的新用户模型兼容 .

  • 3

    不幸的是, django.contrib.auth 中没有任何内容可以简单地进行子类化以获得具有的模型

    • 电子邮件地址代替用户名和

    • 与其他 django.contrib.auth -stuff很好地合作,就像群组一样 .

    最简单的方法是从 django.contrib.auth 复制 models.pyadmin.pyforms.py ,在整个地方删除用户名并放入其中的电子邮件地址's place. I'已经完成,我在几个客户端项目中成功使用它 .

    我已经把它放在github和pypi上,所以你可以安装它

    pip install django-libtech-emailuser
    

    并检查usage instructions on github

相关问题