2013-05-19 55 views
5

我在閱讀文檔:https://docs.djangoproject.com/en/1.5/topics/auth/customizing/#substituting-a-custom-user-model設置電子郵件作爲用戶名的Django 1.5

所以在我的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

有什麼不對?

回答

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 "https://stackoverflow.com/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,並將其重新定義爲與使用電子郵件字段作爲唯一標識符的新用戶模型兼容。

+0

我得到「FieldError:類‘用戶’本地場‘電子郵件’從AbstractUser繼承後,與基類「AbstractUser」中名稱類似的字段發生衝突。 –

+0

更新了答案。首先,我只是提到,AbstractBaseUser沒有電子郵件字段,但是它的寫法存在問題,確實如此。 – stalk

3

不幸的是內django.contrib.auth什麼,你可以簡單地繼承得到的是有地方的用戶名的

  1. 電子郵件地址和

  2. 作品很好地與其他django.contrib.auth -stuff,像集團的範本。

最簡單的方法是從django.contrib.auth複製models.pyadmin.pyforms.py,撕裂了用戶名所有的地方,並把在電子郵件地址,它的位置。我已經完成了這個工作,並且在幾個客戶項目中成功地使用了它。

我已經把它在github和PyPI中,您可以與

pip install django-libtech-emailuser 

安裝並檢查usage instructions on github

+0

在Django 1.5中很好用。我使用github上的說明安裝了應用程序,然後將'from django.contrib.auth.models import User'中的任何實例替換爲'from emailuser.models import EmailUser'和任何引用的User'與'EmailUser'。不知道爲什麼使用電子郵件作爲用戶名的常見做法對於Django來說只是微不足道的,但即使1.5中有這些新功能也是如此。感謝分享。 – Banjer

相關問題