Estendendo o modelo de usuário com campos personalizados no Django

votos
361

Qual é a melhor maneira de estender o modelo do usuário (empacotado com aplicativo de autenticação do Django) com campos personalizados? Eu também, possivelmente, gosto de usar o e-mail como o nome de usuário (para fins de autenticação).

Eu já vi um algumas maneiras de fazê-lo, mas não pode decidir sobre qual é o melhor.

Publicado 04/09/2008 em 17:19
fonte usuário
Em outras línguas...                            


10 respostas

votos
213

Nota: esta resposta está obsoleta. veja outras respostas se você estiver usando Django 1.7 ou posterior.

Isto é como eu faço isso.

#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'

Isto irá criar uma userprofile cada vez que um usuário é salvo se for criada. então você pode usar

  user.get_profile().whatever

Aqui está mais algumas informações dos docs

http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users

Update: Por favor note que AUTH_PROFILE_MODULEestá obsoleto desde v1.5: https://docs.djangoproject.com/en/1.5/ref/settings/#auth-profile-module

Respondeu 08/06/2009 em 17:53
fonte usuário

votos
210

A maneira menos dolorosa e de fato Django-recomendada de fazer isso é através de uma OneToOneField(User)propriedade.

Estendendo o modelo de usuário existente

...

Se você deseja armazenar informações relacionadas com User, você pode usar um relacionamento um-para-um com um modelo que contém os campos para informações adicionais. Este modelo one-to-one é muitas vezes chamado um modelo de perfil, uma vez que pode armazenar informações relacionadas não-auth sobre um usuário do site.

Dito isto, estendendo django.contrib.auth.models.Usere suplantando ele também funciona ...

Substituindo um modelo de usuário personalizada

Alguns tipos de projetos podem ter requisitos de autenticação para o qual built-in do Django Usermodelo nem sempre é apropriado. Por exemplo, em alguns sites que faz mais sentido usar um endereço de e-mail como sua identificação simbólica em vez de um nome de usuário.

[Ed: Duas advertências e um follow notificação , mencionando que este é muito drástica .]

Com certeza, ficaria longe de mudar a classe de usuário real em sua árvore e / ou cópia fonte de Django e alterando o módulo auth.

Respondeu 04/09/2008 em 18:02
fonte usuário

votos
179

Bem, algum tempo passou desde 2008 e é hora de alguma resposta fresco. Desde Django 1.5 você será capaz de criar classe de usuário personalizada. Na verdade, no momento eu estou escrevendo este, já está incorporada mestre, para que você possa experimentá-lo.

Há algumas informações sobre ele em docs ou se você quiser ir mais fundo nele, no presente cometem .

Tudo que você tem a fazer é adicionar AUTH_USER_MODELa configurações com o caminho para a classe de usuário personalizada, que se estende tanto AbstractBaseUser(versão mais personalizável) ou AbstractUser(mais ou menos classe de usuário de idade você pode estender).

Para as pessoas que são preguiçosos para clicar, aqui está exemplo de código (tirado de documentos ):

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
Respondeu 28/09/2012 em 23:22
fonte usuário

votos
41

Há uma recomendação oficial em armazenar informações adicionais sobre os usuários . O Livro Django também discute este problema na seção Perfis .

Respondeu 04/09/2008 em 17:35
fonte usuário

votos
39

Desde Django 1.5 você pode facilmente estender o modelo de usuário e manter uma única tabela no banco de dados.

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"))

Você também deve configurá-lo como classe de usuário atual em seu arquivo de configurações

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

Se você quiser adicionar um monte de preferências dos usuários a opção OneToOneField pode ser um melhor pensamento escolha.

Uma nota para as pessoas em desenvolvimento bibliotecas de terceiros: se você precisar acessar a classe de usuário lembrar que as pessoas podem mudá-lo. Use o ajudante oficial para obter a classe certa

from django.contrib.auth import get_user_model

User = get_user_model()
Respondeu 20/04/2013 em 22:56
fonte usuário

votos
21

O abaixo é uma outra abordagem para estender um usuário. Eu sinto que é mais clara, fácil e legível, em seguida, acima de duas abordagens.

http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/

Usando acima abordagem:

  1. você não precisa usar user.get_profile (). NewAttribute para acessar as informações adicionais relacionadas com o usuário
  2. você pode apenas acessar diretamente novos atributos adicionais através user.newattribute
Respondeu 01/04/2009 em 14:01
fonte usuário

votos
9

Você pode simplesmente estender o perfil de usuário através da criação de uma nova entrada de cada vez quando o usuário é criado usando pós django salvar sinais

models.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)

Isto irá criar automaticamente uma instância empregado quando um novo usuário é criado.

Se desejar prolongar modelo de usuário e deseja adicionar mais informações ao criar usuário, você pode usar o Django-betterforms ( http://django-betterforms.readthedocs.io/en/latest/multiform.html ). Isto irá criar um formulário do usuário add com todos os campos definidos no modelo userProfile.

models.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,
    }

views.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'),
]
Respondeu 25/06/2016 em 03:09
fonte usuário

votos
7

Estendendo Django Modelo de Usuário (UserProfile) como um Pro

Eu achei isso muito útil: ligação

Um extrato:

de django.contrib.auth.models usuário de importação

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
Respondeu 13/04/2016 em 08:09
fonte usuário

votos
2

Novo no Django 1.5, agora você pode criar seu próprio modelo personalizado do usuário (o que parece ser uma boa coisa a fazer no caso acima). Consulte 'Personalizando a autenticação no Django'

Provavelmente o mais legal novo recurso no release 1.5.

Respondeu 12/03/2013 em 11:01
fonte usuário

votos
0

Isto é o que eu faço e é na minha opinião maneira mais simples de fazer isso. definir um gerenciador de objetos para o seu novo modelo personalizado, em seguida, definir o seu 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

Não se esqueça de adicionar esta linha de código em seu settings.py:

AUTH_USER_MODEL = 'YourApp.User'

Isto é o que eu faço e sempre funciona.

Respondeu 25/07/2018 em 05:00
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more