tipos campos django django-authentication django-users

tipos - Ampliación del modelo de usuario con campos personalizados en Django.



django user model (10)

¿Cuál es la mejor manera de extender el modelo de usuario (incluido con la aplicación de autenticación de Django) con campos personalizados? También me gustaría utilizar el correo electrónico como nombre de usuario (con fines de autenticación).

Ya he visto few ways de hacerlo, pero no puedo decidir cuál es la mejor.


Bueno, pasó un tiempo desde 2008 y es hora de una nueva respuesta. Desde Django 1.5 podrás crear una clase de usuario personalizada. En realidad, en el momento en que escribo esto, ya está fusionado con el maestro, por lo que puedes probarlo.

Hay algo de información al respecto en los docs o si desea profundizar más en este compromiso .

Todo lo que tiene que hacer es agregar AUTH_USER_MODEL a la configuración con ruta a la clase de usuario personalizada, que extiende a AbstractBaseUser (versión más personalizable) o AbstractUser (más o menos antigua clase de Usuario que puede extender).

Para las personas que son perezosas de hacer clic, aquí hay un ejemplo de código (tomado de docs ):

from django.db import models from django.contrib.auth.models import ( BaseUserManager, AbstractBaseUser ) class MyUserManager(BaseUserManager): def create_user(self, email, date_of_birth, password=None): """ Creates and saves a User with the given email, date of birth and password. """ if not email: raise ValueError(''Users must have an email address'') user = self.model( email=MyUserManager.normalize_email(email), date_of_birth=date_of_birth, ) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, username, date_of_birth, password): """ Creates and saves a superuser with the given email, date of birth and password. """ u = self.create_user(username, password=password, date_of_birth=date_of_birth ) u.is_admin = True u.save(using=self._db) return u class MyUser(AbstractBaseUser): email = models.EmailField( verbose_name=''email address'', max_length=255, unique=True, ) date_of_birth = models.DateField() is_active = models.BooleanField(default=True) is_admin = models.BooleanField(default=False) objects = MyUserManager() USERNAME_FIELD = ''email'' REQUIRED_FIELDS = [''date_of_birth''] def get_full_name(self): # The user is identified by their email address return self.email def get_short_name(self): # The user is identified by their email address return self.email def __unicode__(self): return self.email def has_perm(self, perm, obj=None): "Does the user have a specific permission?" # Simplest possible answer: Yes, always return True def has_module_perms(self, app_label): "Does the user have permissions to view the app `app_label`?" # Simplest possible answer: Yes, always return True @property def is_staff(self): "Is the user a member of staff?" # Simplest possible answer: All admins are staff return self.is_admin


Desde Django 1.5 puede extender fácilmente el modelo de usuario y mantener una sola tabla en la base de datos.

from django.contrib.auth.models import AbstractUser from django.db import models from django.utils.translation import ugettext_lazy as _ class UserProfile(AbstractUser): age = models.PositiveIntegerField(_("age"))

También debe configurarlo como clase de usuario actual en su archivo de configuración

# supposing you put it in apps/profiles/models.py AUTH_USER_MODEL = "profiles.UserProfile"

Si desea agregar muchas preferencias de usuarios, la opción OneToOneField puede ser una opción mejor pensada.

Una nota para las personas que desarrollan bibliotecas de terceros: si necesita acceder a la clase de usuario, recuerde que las personas pueden cambiarla. Usa el ayudante oficial para obtener la clase correcta

from django.contrib.auth import get_user_model User = get_user_model()


El siguiente es otro enfoque para extender un usuario. Siento que es más claro, fácil, legible que por encima de dos enfoques.

few

Utilizando el enfoque anterior:

  1. no necesita utilizar user.get_profile (). newattribute para acceder a la información adicional relacionada con el usuario
  2. puede acceder directamente a nuevos atributos adicionales a través de user.newattribute

Esto es lo que hago y es, en mi opinión, la forma más sencilla de hacerlo. define un administrador de objetos para tu nuevo modelo personalizado y luego define tu modelo.

from django.db import models from django.contrib.auth.models import PermissionsMixin, AbstractBaseUser, BaseUserManager class User_manager(BaseUserManager): def create_user(self, username, email, gender, nickname, password): email = self.normalize_email(email) user = self.model(username=username, email=email, gender=gender, nickname=nickname) user.set_password(password) user.save(using=self.db) return user def create_superuser(self, username, email, gender, password, nickname=None): user = self.create_user(username=username, email=email, gender=gender, nickname=nickname, password=password) user.is_superuser = True user.is_staff = True user.save() return user class User(PermissionsMixin, AbstractBaseUser): username = models.CharField(max_length=32, unique=True, ) email = models.EmailField(max_length=32) gender_choices = [("M", "Male"), ("F", "Female"), ("O", "Others")] gender = models.CharField(choices=gender_choices, default="M", max_length=1) nickname = models.CharField(max_length=32, blank=True, null=True) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) REQUIRED_FIELDS = ["email", "gender"] USERNAME_FIELD = "username" objects = User_manager() def __str__(self): return self.username

No olvide agregar esta línea de código en su settings.py :

AUTH_USER_MODEL = ''YourApp.User''

Esto es lo que hago y siempre funciona.



Nuevo en Django 1.5, ahora puede crear su propio Modelo de Usuario Personalizado (lo que parece ser algo bueno en el caso anterior). Consulte ''Personalización de la autenticación en Django''.

Probablemente la nueva característica más genial en la versión 1.5.


Simplemente puede ampliar el perfil de usuario creando una nueva entrada cada vez que se cree un usuario utilizando las señales de guardado de django

modelos.py

from django.db.models.signals import * from __future__ import unicode_literals class userProfile(models.Model): userName = models.OneToOneField(User, related_name=''profile'') city = models.CharField(max_length=100, null=True) def __unicode__(self): # __str__ return unicode(self.userName) def create_user_profile(sender, instance, created, **kwargs): if created: userProfile.objects.create(userName=instance) post_save.connect(create_user_profile, sender=User)

Esto creará automáticamente una instancia de empleado cuando se crea un nuevo usuario.

Si desea ampliar el modelo de usuario y desea agregar más información mientras lo crea, puede usar django-betterforms ( http://django-betterforms.readthedocs.io/en/latest/multiform.html ). Esto creará un formulario de adición de usuario con todos los campos definidos en el modelo de perfil de usuario.

modelos.py

from django.db.models.signals import * from __future__ import unicode_literals class userProfile(models.Model): userName = models.OneToOneField(User) city = models.CharField(max_length=100) def __unicode__(self): # __str__ return unicode(self.userName)

forms.py

from django import forms from django.forms import ModelForm from betterforms.multiform import MultiModelForm from django.contrib.auth.forms import UserCreationForm from .models import * class profileForm(ModelForm): class Meta: model = Employee exclude = (''userName'',) class addUserMultiForm(MultiModelForm): form_classes = { ''user'':UserCreationForm, ''profile'':profileForm, }

vistas.py

from django.shortcuts import redirect from .models import * from .forms import * from django.views.generic import CreateView class addUser(CreateView): form_class = addUserMultiForm template_name = "addUser.html" success_url = ''/your url after user created'' def form_valid(self, form): user = form[''user''].save() profile = form[''profile''].save(commit=False) profile.userName = User.objects.get(username= user.username) profile.save() return redirect(self.success_url)

addUser.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="." method="post"> {% csrf_token %} {{ form }} <button type="submit">Add</button> </form> </body> </html>

urls.py

from django.conf.urls import url, include from appName.views import * urlpatterns = [ url(r''^add-user/$'', addUser.as_view(), name=''addDistributor''), ]


Ampliación del modelo de usuario de Django (perfil de usuario) como un profesional

He encontrado esto muy útil: link

Un extracto:

desde django.contrib.auth.models import User

class Employee(models.Model): user = models.OneToOneField(User) department = models.CharField(max_length=100) >>> u = User.objects.get(username=''fsmith'') >>> freds_department = u.employee.department


Nota: esta respuesta está en desuso. Vea otras respuestas si está utilizando Django 1.7 o posterior.

Así es como lo hago.

#in models.py from django.contrib.auth.models import User from django.db.models.signals import post_save class UserProfile(models.Model): user = models.OneToOneField(User) #other fields here def __str__(self): return "%s''s profile" % self.user def create_user_profile(sender, instance, created, **kwargs): if created: profile, created = UserProfile.objects.get_or_create(user=instance) post_save.connect(create_user_profile, sender=User) #in settings.py AUTH_PROFILE_MODULE = ''YOURAPP.UserProfile''

Esto creará un perfil de usuario cada vez que se guarde un usuario si se crea. A continuación, puede utilizar

user.get_profile().whatever

Aquí hay más información de la documentación.

docs.djangoproject.com/en/dev/topics/auth/…

Actualización: tenga en cuenta que AUTH_PROFILE_MODULE está en desuso desde v1.5: https://docs.djangoproject.com/en/1.5/ref/settings/#auth-profile-module


La forma menos dolorosa y, de hecho, recomendada por Django para hacer esto es a través de la propiedad OneToOneField(User) .

Ampliación del modelo de usuario existente.

...

Si desea almacenar información relacionada con el User , puede usar una relación de uno a uno con un modelo que contiene los campos para obtener información adicional. Este modelo uno a uno a menudo se denomina modelo de perfil, ya que puede almacenar información no relacionada con la autenticación de un usuario del sitio.

Dicho esto, extender django.contrib.auth.models.User y suplantarlo también funciona ...

Sustituyendo un modelo de usuario personalizado

Algunos tipos de proyectos pueden tener requisitos de autenticación para los cuales el modelo de User incorporado de Django no siempre es apropiado. Por ejemplo, en algunos sitios tiene más sentido utilizar una dirección de correo electrónico como su token de identificación en lugar de un nombre de usuario.

[Ed: Dos advertencias y una notificación siguen , mencionando que esto es bastante drástico .]

Definitivamente me mantendría alejado de cambiar la clase de usuario real en el árbol de origen de Django y / o copiar y alterar el módulo de autenticación.