2013-05-19 10 views
5

sto leggendo la documentazione a: https://docs.djangoproject.com/en/1.5/topics/auth/customizing/#substituting-a-custom-user-modelImposta posta elettronica come nome utente in Django 1.5

Così nel mio settings.py ho messo:

AUTH_USER_MODEL = 'membership.User' 

E nella mia appartenenza app models.py ho questo:

from django.contrib.auth.models import AbstractBaseUser 

class User(AbstractBaseUser): 
    USERNAME_FIELD = 'email' 

esecuzione pitone manage.py syncdb mi sta dando:

FieldDoesNotExist: User has no field named 'email' 

ho controllare sorgente della classe AbstractBaseUser e il campo è definito, naturalmente, come si può vedere qui: https://github.com/django/django/blob/master/django/contrib/auth/models.py#L359

Cosa c'è di sbagliato?

risposta

18

AbstractBaseUser non ha campo di posta elettronica, lo AbstractUser fa.

Se si desidera utilizzare la posta elettronica come un identificatore univoco, allora avete bisogno di sottoclasse da AbstractBaseUser e definire campo email con unique=True e anche scrivere altre funzionalità, ad esempio Manager del modello:

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 

Inoltre, probabilmente vorrai aggiungere questo utente alla pagina di amministrazione. Guarda UserAdmin e ridefiniscilo per essere compatibile con il nuovo modello utente, che usa il campo email come identificativo univoco.

+0

sto ottenendo "FieldError: campo 'email' locale in class 'utente' si scontra con il campo di nome simile dalla classe base 'AbstractUser' "dopo aver ereditato da AbstractUser. –

+0

Aggiornamento della risposta. Per prima cosa ho appena detto, che AbstractBaseUser non ha campo di posta elettronica, ma è stato scritto in questione, che lo fa. – stalk

3

Purtroppo non c'è niente dentro django.contrib.auth che si può semplicemente sottoclasse di ottenere un modello che ha

  1. indirizzo e-mail al posto del nome utente e

  2. funziona bene con altri django.contrib.auth -stuff, come i gruppi .

L'approccio più semplice è quello di copiare models.py, admin.py e forms.py da django.contrib.auth, strappare il nome utente in tutto il luogo e mettere in indirizzo di posta elettronica al suo posto. Ho fatto proprio questo e lo sto usando con successo in un paio di progetti client.

ho messo su github e PyPI modo da poter installare con

pip install django-libtech-emailuser 

e controllare il usage instructions on github

+0

Funziona alla grande in Django 1.5. Ho installato la tua app con le istruzioni che hai su github e poi ho appena sostituito qualsiasi istanza nel mio progetto di 'from django.contrib.auth.models import User' con' from emailuser.models import EmailUser' e qualsiasi riferimento di 'User' con 'EmailUser'. Non sono sicuro del motivo per cui la pratica comune di usare una e-mail per un nome utente sarebbe tutt'altro che banale per Django, ma lo è, anche con queste nuove funzionalità in 1.5. Grazie per la condivisione. – Banjer

Problemi correlati