Frage

Was ist der beste Weg, das Benutzermodell (im Paket mit der Authentifizierungs-App von Django) um benutzerdefinierte Felder zu erweitern?Eventuell möchte ich auch die E-Mail als Benutzernamen verwenden (zur Authentifizierung).

Ich habe schon einen gesehen wenige Wege Ich möchte es tun, kann mich aber nicht entscheiden, welches das Beste ist.

War es hilfreich?

Lösung

Der am wenigsten schmerzhafte und tatsächlich von Django empfohlene Weg, dies zu tun, ist a OneToOneField(User) Eigentum.

Erweiterung des bestehenden Benutzermodells

Wenn Sie Informationen im Zusammenhang mit speichern möchten User, können Sie a verwenden 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 möglicherweise nicht authentisierungsbezogene Informationen über einen Site-Benutzer speichert.

Das heißt, verlängern django.contrib.auth.models.User und das Ersetzen funktioniert auch ...

Ersetzen eines benutzerdefinierten Benutzermodells

Für einige Arten von Projekten gelten möglicherweise Authentifizierungsanforderungen, die in Django integriert sind User Modell ist nicht immer angemessen.Auf einigen Websites ist es beispielsweise sinnvoller, eine E-Mail-Adresse anstelle eines Benutzernamens als Identifikationsmerkmal zu verwenden.

[Hrsg.: Es folgen zwei Warnungen und eine Benachrichtigung, erwähnend, dass dies der Fall ist ziemlich drastisch.]

Ich würde auf jeden Fall davon Abstand nehmen, die tatsächliche Benutzerklasse in Ihrem Django-Quellbaum zu ändern und/oder das Authentifizierungsmodul zu kopieren und zu ändern.

Andere Tipps

Notiz:Diese Antwort ist veraltet.Sehen Sie sich andere Antworten an, 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 jedes Mal, wenn ein Benutzer erstellt wird, ein Benutzerprofil erstellt.Sie können es dann verwenden

  user.get_profile().whatever

Hier sind einige weitere Informationen aus den Dokumenten

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

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

Nun, seit 2008 ist einige Zeit vergangen und es ist Zeit für eine neue Antwort.Seit Django 1.5 können Sie benutzerdefinierte Benutzerklassen erstellen.Tatsächlich ist es zu dem Zeitpunkt, als ich dies schreibe, bereits in den Master eingebunden, sodass Sie es ausprobieren können.

Es gibt einige Informationen dazu in Dokumente oder wenn Sie tiefer in die Materie eintauchen möchten, in dieses Commit.

Alles, was Sie tun müssen, ist hinzuzufügen AUTH_USER_MODEL zu den Einstellungen mit dem Pfad zur benutzerdefinierten Benutzerklasse, die beide erweitert AbstractBaseUser (anpassbarere Version) oder AbstractUser (Mehr oder weniger alte Benutzerklasse, die Sie erweitern können).

Für Leute, die klickfaul sind, hier ein Codebeispiel (entnommen aus Dokumente):

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

Seit Django 1.5 können Sie das Benutzermodell problemlos erweitern und eine einzelne Tabelle in der Datenbank behalten.

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 es 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 möglicherweise die bessere Wahl.

Ein Hinweis für Leute, die Bibliotheken von Drittanbietern entwickeln:Wenn Sie auf die Benutzerklasse zugreifen müssen, denken Sie daran, dass diese geändert werden kann.Nutzen Sie den offiziellen Helfer, um die richtige Klasse zu finden

from django.contrib.auth import get_user_model

User = get_user_model()

Es gibt eine offizielle Empfehlung dazu Speicherung zusätzlicher Informationen über Benutzer.Das Django-Buch behandelt dieses Problem ebenfalls in einem Abschnitt Profile.

Das Folgende ist ein weiterer Ansatz zum Erweitern eines Benutzers.Meiner Meinung nach ist es klarer, einfacher und lesbarer als die beiden oben genannten Ansätze.

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

Verwendung des obigen Ansatzes:

  1. Sie müssen es nicht verwendenuser.get_profile().newattribute So greifen Sie auf die zusätzlichen Informationen im Zusammenhang mit dem Benutzer zu
  2. Sie können einfach direkt auf zusätzliche neue Attribute zugreifenuser.newattribute

Sie können das Benutzerprofil einfach erweitern, indem Sie jedes Mal, wenn ein Benutzer erstellt wird, mithilfe von Django-Post-Save-Signalen einen neuen Eintrag erstellen

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)

Dadurch wird automatisch eine Mitarbeiterinstanz erstellt, wenn ein neuer Benutzer erstellt wird.

Wenn Sie das Benutzermodell erweitern und beim Erstellen eines Benutzers weitere Informationen hinzufügen möchten, können Sie django-betterforms (http://django-betterforms.readthedocs.io/en/latest/multiform.html).Dadurch wird ein Formular zum Hinzufügen eines Benutzers mit allen im userProfile-Modell definierten Feldern erstellt.

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)

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

Ansichten.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'),
]

Erweitern Sie das Django-Benutzermodell (UserProfile) wie ein Profi

Ich fand das sehr nützlich: Verknüpfung

Ein Auszug:

aus django.contrib.auth.models Benutzer importieren

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

Neu in Django 1.5: Jetzt können Sie Ihr eigenes benutzerdefiniertes Benutzermodell erstellen (was im obigen Fall eine gute Sache zu sein scheint).Beziehen auf „Anpassen der Authentifizierung in Django“

Wahrscheinlich die coolste neue Funktion in Version 1.5.

Das mache ich und es ist meiner Meinung nach der einfachste Weg, dies zu tun.Definieren Sie einen Objektmanager für Ihr neues benutzerdefiniertes Modell und definieren Sie dann Ihr Modell.

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

Vergessen Sie nicht, diese Codezeile in Ihre Datei einzufügen settings.py:

AUTH_USER_MODEL = 'YourApp.User'

Das mache ich und es funktioniert immer.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top