L'utilisation de l'email comme champ de nom d'utilisateur dans Django 1.5 custom User model entraîne FieldError
Je souhaite utiliser un champ email comme champ Nom d'utilisateur pour mon modèle d'utilisateur personnalisé. J'ai le modèle utilisateur personnalisé suivant sous-classant le modèle AbstractUser de Django:
class CustomUser(AbstractUser):
....
email = models.EmailField(max_length=255, unique=True)
USERNAME_FIELD = 'email'
Mais quand je cours
Python manage.py sql myapp
Je reçois l'erreur suivante:
FieldError: le champ Local 'email' de la classe 'CustomUser' se heurte à un champ de nom similaire de la classe de base 'AbstractUser'
La raison pour laquelle j'inclus mon propre champ email dans le premier le lieu est d'ajouter l'option unique=True
. sinon, je reçois:
Myapp.customuser: le champ USERNAME_FIELD doit être unique. Ajoutez unique = True aux paramètres du champ.
Maintenant, en ce qui concerne cette:
https://docs.djangoproject.com/en/1.5/topics/db/models/#field-name-hiding-is-not-permitted
Comment puis-je y parvenir? (autre que de nommer le champ "user_email" ou quelque chose comme ça à la place)
4 réponses
Ian, je vous remercie beaucoup pour la réponse intelligente:)
Cependant, je me suis déjà "patché" une solution.
Puisque AbstractUser
ont aussi un champ username
qui est totalement inutile pour moi
J'ai décidé de créer mon "propre" AbstractUser
.
En sous-classant AbstractBaseUser
et PermissionsMixin
je conserve la plupart des méthodes intégrées du modèle utilisateur sans ajouter de code.
J'ai également profité de cette opportunité pour créer un Manager
personnalisé pour éliminer l'utilisation dans le Champ username
all ensemble:
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
class CustomUser(AbstractBaseUser, PermissionsMixin):
....
email = models.EmailField(max_length=255, unique=True)
first_name = ...
last_name = ...
is_active = ...
is_staff = ...
....
objects = CustomUserManager()
USERNAME_FIELD = 'email'
class CustomUserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
.....
def create_superuser(self, email, password, **extra_fields):
.....
Cette solution entraîne la répétition d'une partie du code intégré de Django (principalement des champs de modèle qui existent déjà dans AbstractUser
tels que 'first_name', 'last_name' etc.) mais aussi dans un objet utilisateur plus propre et une table de base de données.
Il est vraiment dommage que le flexibily introduit en 1.5 avec USERNAME_FIELD
ne puisse pas être utilisé pourréellement créer un modèle utilisateur flexible sous toutes les contraintes existantes.
EDIT: il y a un exemple complet travaillé disponible dans les documents officiels: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#a-full-example
Si votre cible réelle est des valeurs "email" uniques, et en ignorant les valeurs "username", alors vous pouvez:
- remplissez "nom d'utilisateur" avec par exemple
sha256(user.email).hexdigest()[:30]
-
Ajouter unicité de cette façon:
class User(AbstractUser): class Meta: unique_together = ('email', )
Il en résulte:
CREATE TABLE "myapp_user" (
...
"email" varchar(75) NOT NULL,
UNIQUE ("email")
)
Fonctionne comme prévu, et est assez simple.
, Vous pouvez modifier votre CustomUser
pour modifier la email
champ attribut unique=True
.
Ajoutez ceci à la fin de votre classe utilisateur personnalisée comme ceci:
class CustomUser(AbstractUser):
...
USERNAME_FIELD = 'email'
...
CustomUser._meta.get_field_by_name('email')[0]._unique=True
Notez que nous changeons _unique
et non unique
parce que ce dernier est un simple @property
.
C'est un hack, et j'aimerais entendre des réponses "officielles" pour résoudre ce problème.
Utiliser l'exemple du site officiel :
Https://docs.djangoproject.com/en/1.7/topics/auth/customizing/#a-full-example
Voici un exemple d'application utilisateur personnalisée compatible admin. Ce modèle d'utilisateur utilise une adresse e-mail comme nom d'utilisateur et a une date de naissance requise; il ne fournit aucune vérification d'autorisation, au-delà d'un simple indicateur admin sur le compte d'utilisateur. Ce modèle serait compatible avec toutes les formes et vues auth intégrées, à l'exception de L'utilisateur les formes de la création. Cet exemple illustre comment la plupart des composants fonctionnent ensemble, mais n'est pas destiné à être copié directement dans des projets pour une utilisation en production.