2013-05-19 14 views
5

Czytam docs na: https://docs.djangoproject.com/en/1.5/topics/auth/customizing/#substituting-a-custom-user-modelSet email jako nazwa użytkownika w Django 1.5

Więc w moim settings.py kładę:

AUTH_USER_MODEL = 'membership.User' 

I w moim członków app models.py mam to:

from django.contrib.auth.models import AbstractBaseUser 

class User(AbstractBaseUser): 
    USERNAME_FIELD = 'email' 

Running python manage.py syncdb daje mi:

FieldDoesNotExist: User has no field named 'email' 

Sprawdzam źródło klasy AbstractBaseUser, a pole jest zdefiniowane oczywiście, jak widać tutaj: https://github.com/django/django/blob/master/django/contrib/auth/models.py#L359

Co jest nie tak?

Odpowiedz

18

AbstractBaseUser nie ma pola wiadomości e-mail, czyli AbstractUser.

Jeśli chcesz korzystać z e-mail jako unikalny identyfikator, a następnie trzeba podklasy z AbstractBaseUser i zdefiniować pole e-mail z unique=True a także napisać inne funkcje, na przykład Manager modelu:

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 

także prawdopodobnie będziesz chciał dodać tego użytkownika do strony administratora. Spójrz na UserAdmin i przedefiniuj go, aby był zgodny z nowym modelem użytkownika, który używa pola e-mail jako unikalnego identyfikatora.

+0

otrzymuję „FieldError: Local pole 'Wiadomość' w klasie 'user' zderza się z polem o podobnej nazwie z klasy bazowej "AbstractUser" po odziedziczeniu po AbstractUser. –

+0

Zaktualizowano odpowiedź. Najpierw wspomnę tylko, że AbstractBaseUser nie ma pola emailowego, ale zostało napisane w pytaniu, że tak. – stalk

3

Niestety nie ma nic wewnątrz django.contrib.auth, że można po prostu podklasy uzyskać model, który ma

  1. adres e-mail zamiast nazwy użytkownika i

  2. działa dobrze z innymi django.contrib.auth -stuff, jak grupy .

Najprostszym rozwiązaniem jest skopiować models.py, admin.py i forms.py z django.contrib.auth, wyrwać nazwę użytkownika w każdym miejscu i umieścić na adres e-mail w to miejsce. Właśnie to zrobiłem i używam go z powodzeniem w kilku projektach klientów.

Wrzuciłem go na github i PyPI więc można go zainstalować z

pip install django-libtech-emailuser 

i sprawdź usage instructions on github

+0

Działa doskonale w Django 1.5. Zainstalowałem Twoją aplikację z instrukcjami, które posiadasz na github, a następnie po prostu zastąpiłeś dowolne wystąpienie w moim projekcie 'from django.contrib.auth.models importuj użytkownika' 'z emailuser.models importuj EmailUser' i wszelkie odniesienia do' Użytkownika' z 'EmailUser'. Nie wiem, dlaczego powszechna praktyka używania e-maila do nazwy użytkownika byłaby dla Django niczym innym, jak tylko z tymi nowymi funkcjami w wersji 1.5. Dziękuję za udostępnienie. – Banjer

Powiązane problemy