546 Stimmen

Erweitern des Benutzermodells mit benutzerdefinierten Feldern in Django

Was ist der beste Weg, um das Benutzer-Modell (gebündelt mit Djangos Authentifizierung app) mit benutzerdefinierten Feldern zu erweitern? Ich möchte auch möglicherweise die E-Mail als Benutzername (für Authentifizierungszwecke) zu verwenden.

Ich habe bereits eine wenige Wege aber ich kann mich nicht entscheiden, welches die beste Lösung ist.

311voto

Ryan Duffield Punkte 17639

Der am wenigsten schmerzhafte und in der Tat von Django empfohlene Weg, dies zu tun, ist durch eine OneToOneField(User) Eigentum.

Erweiterung des bestehenden Benutzermodells

Wenn Sie Informationen zu folgenden Themen speichern möchten User können Sie eine Eins-zu-Eins-Beziehung zu einem Modell, das die Felder für zusätzliche Informationen enthält. Dieses Eins-zu-eins-Modell wird oft als Profilmodell bezeichnet, da es auch nicht-auth-bezogene Informationen über einen Website-Benutzer speichern kann.

Das heißt, die Verlängerung django.contrib.auth.models.User und die Verdrängung funktioniert auch...

Ersetzen eines benutzerdefinierten Benutzermodells

Einige Arten von Projekten können Authentifizierungsanforderungen haben, für die die in Django integrierte User Modell ist nicht immer angemessen. Auf manchen Websites ist es zum Beispiel sinnvoller, eine E-Mail-Adresse als Identifikationsmerkmal zu verwenden als einen Benutzernamen.

[Ed: Es folgen zwei Warnungen und eine Benachrichtigung mit dem Hinweis, dass es sich um ziemlich krass .]

Ich würde auf jeden Fall bleiben weg von der Änderung der tatsächlichen Benutzer-Klasse in Ihrem Django-Quellbaum und / oder Kopieren und Ändern der Auth-Modul.

240voto

Raisins Punkte 2788

Hinweis: Diese Antwort ist veraltet. Siehe andere Antworten, wenn Sie Django 1.7 oder höher verwenden.

So mache ich es.

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

Dadurch wird bei jedem Speichern eines Benutzers ein Benutzerprofil erstellt, wenn es erstellt wird. Sie können dann

  user.get_profile().whatever

Hier einige weitere Informationen aus den Dokumenten

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

Aktualisierung: Bitte beachten Sie, dass AUTH_PROFILE_MODULE ist seit v1.5 veraltet: https://docs.djangoproject.com/en/1.5/ref/settings/#auth-profile-module

222voto

Ondrej Slinták Punkte 30258

Nun, seit 2008 ist einige Zeit vergangen und es ist Zeit für eine neue Antwort. Seit Django 1.5 werden Sie in der Lage sein, benutzerdefinierte User-Klassen zu erstellen. Zum Zeitpunkt, an dem ich dies schreibe, ist es bereits in Master eingebunden, Sie können es also ausprobieren.

Es gibt einige Informationen darüber in 諸注意 oder, wenn Sie sich eingehender damit befassen wollen, unter diese Verpflichtung .

Alles, was Sie tun müssen, ist hinzufügen AUTH_USER_MODEL zu den Einstellungen mit dem Pfad zur benutzerdefinierten Benutzerklasse, die entweder AbstractBaseUser (besser anpassbare Version) oder AbstractUser (mehr oder weniger alte Benutzerklasse, die Sie erweitern können).

Für Leute, die zu faul zum Klicken sind, hier ein Code-Beispiel (entnommen aus 諸注意 ) :

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

63voto

Riccardo Galli Punkte 11416

Seit Django 1.5 kann man das Benutzermodell einfach erweitern und eine einzelne Tabelle in der Datenbank führen.

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

Sie müssen ihn auch als aktuelle Benutzerklasse in Ihrer Einstellungsdatei konfigurieren

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

Wenn Sie viele Benutzereinstellungen hinzufügen möchten, ist die Option OneToOneField vielleicht die bessere Wahl.

Ein Hinweis für Entwickler von Bibliotheken von Drittanbietern: Wenn Sie auf die Benutzerklasse zugreifen müssen, denken Sie daran, dass sie von anderen geändert werden kann. Verwenden Sie die offizielle Hilfe, um die richtige Klasse zu erhalten

from django.contrib.auth import get_user_model

User = get_user_model()

47voto

Dmitry Mukhin Punkte 6108

Es gibt eine offizielle Empfehlung zu Speicherung zusätzlicher Informationen über Benutzer . Das Django-Buch erörtert dieses Problem auch im Abschnitt Profile .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X