سؤال

ما هي أفضل طريقة لتوسيع نموذج المستخدم (المرفق مع تطبيق مصادقة Django) باستخدام الحقول المخصصة؟ربما أرغب أيضًا في استخدام البريد الإلكتروني كاسم مستخدم (لأغراض المصادقة).

لقد رأيت بالفعل أ عدد قليل طرق للقيام بذلك، ولكن لا يمكن أن تقرر أي واحد هو الأفضل.

هل كانت مفيدة؟

المحلول

الطريقة الأقل إيلامًا والموصى بها بالفعل من قبل جانغو للقيام بذلك هي من خلال ملف OneToOneField(User) ملكية.

توسيع نموذج المستخدم الحالي

إذا كنت ترغب في تخزين المعلومات المتعلقة User, ، يمكنك استخدام أ علاقة فردية إلى نموذج يحتوي على الحقول للحصول على معلومات إضافية.غالبًا ما يُطلق على نموذج رأس برأس هذا اسم نموذج الملف الشخصي، لأنه قد يقوم بتخزين معلومات غير متعلقة بالمصادقة حول مستخدم الموقع.

وقيل: يمتد django.contrib.auth.models.User واستبداله يعمل أيضًا ...

استبدال نموذج مستخدم مخصص

قد تحتوي بعض أنواع المشاريع على متطلبات مصادقة مدمجة في برنامج Django User النموذج ليس مناسبًا دائمًا.على سبيل المثال، في بعض المواقع يكون من المنطقي استخدام عنوان البريد الإلكتروني كرمز تعريفي بدلاً من اسم المستخدم.

[إد: اتبع تحذيرين وإخطار, ، مشيراً إلى أن هذا جذرية جدا.]

سأبتعد بالتأكيد عن تغيير فئة المستخدم الفعلية في شجرة مصدر Django و/أو نسخ وحدة المصادقة وتغييرها.

نصائح أخرى

ملحوظة:تم إهمال هذه الإجابة.راجع الإجابات الأخرى إذا كنت تستخدم Django 1.7 أو إصدار أحدث.

هذه هي الطريقة التي أفعل ذلك.

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

سيؤدي هذا إلى إنشاء ملف تعريف مستخدم في كل مرة يتم فيها حفظ المستخدم إذا تم إنشاؤه.يمكنك بعد ذلك استخدام

  user.get_profile().whatever

إليك بعض المعلومات الإضافية من المستندات

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

تحديث: يرجى ملاحظة ذلك AUTH_PROFILE_MODULE تم إهماله منذ الإصدار 1.5: https://docs.djangoproject.com/en/1.5/ref/settings/#auth-profile-module

حسنًا، لقد مر بعض الوقت منذ عام 2008، وحان الوقت لبعض الإجابات الجديدة.منذ الإصدار 1.5 من Django، ستتمكن من إنشاء فئة مستخدم مخصصة.في الواقع، في الوقت الذي أكتب فيه هذا، تم دمجه بالفعل في الملف الرئيسي، لذا يمكنك تجربته.

هناك بعض المعلومات حول هذا الموضوع في مستندات أو إذا كنت ترغب في التعمق في ذلك، في هذا الالتزام.

كل ما عليك فعله هو الإضافة AUTH_USER_MODEL إلى الإعدادات مع المسار إلى فئة المستخدم المخصصة، والتي تمتد أيضًا AbstractBaseUser (نسخة أكثر تخصيصًا) أو AbstractUser (فئة المستخدم القديمة أكثر أو أقل يمكنك تمديدها).

بالنسبة للأشخاص الذين يتكاسلون عن النقر، إليك مثال التعليمات البرمجية (مأخوذ من مستندات):

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

منذ Django 1.5، يمكنك بسهولة توسيع نموذج المستخدم والاحتفاظ بجدول واحد في قاعدة البيانات.

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

يجب عليك أيضًا تكوينها كفئة مستخدم حالية في ملف الإعدادات الخاص بك

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

إذا كنت ترغب في إضافة الكثير من تفضيلات المستخدمين، فقد يكون خيار OneToOneField خيارًا أفضل.

ملاحظة للأشخاص الذين يقومون بتطوير مكتبات الطرف الثالث:إذا كنت بحاجة إلى الوصول إلى فئة المستخدم، فتذكر أنه يمكن للأشخاص تغييرها.استخدم المساعد الرسمي للحصول على الفصل المناسب

from django.contrib.auth import get_user_model

User = get_user_model()

هناك توصية رسمية بشأن تخزين معلومات إضافية عن المستخدمين.يناقش كتاب جانغو أيضًا هذه المشكلة في القسم مظهر.

الطريقة التالية هي طريقة أخرى لتوسيع نطاق المستخدم.أشعر أنه أكثر وضوحًا وسهولة وقابلية للقراءة من النهجين أعلاه.

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

باستخدام النهج أعلاه:

  1. لا تحتاج إلى استخدامuser.get_profile().newattribute للوصول إلى المعلومات الإضافية المتعلقة بالمستخدم
  2. يمكنك فقط الوصول مباشرة إلى سمات جديدة إضافية عبرuser.newattribute

يمكنك ببساطة توسيع ملف تعريف المستخدم عن طريق إنشاء إدخال جديد في كل مرة يتم فيها إنشاء المستخدم باستخدام إشارات حفظ نشر Django

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)

سيؤدي هذا تلقائيًا إلى إنشاء مثيل موظف عند إنشاء مستخدم جديد.

إذا كنت ترغب في توسيع نموذج المستخدم وترغب في إضافة المزيد من المعلومات أثناء إنشاء المستخدم، فيمكنك استخدام Django-betterforms (http://django-betterforms.readthedocs.io/en/latest/multiform.html).سيؤدي هذا إلى إنشاء نموذج إضافة مستخدم بجميع الحقول المحددة في نموذج ملف تعريف المستخدم.

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

وجهات النظر.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'),
]

توسيع نموذج مستخدم Django (ملف المستخدم) مثل المحترفين

لقد وجدت هذا مفيدًا جدًا: وصلة

مقتطف:

من django.contrib.auth.models استيراد المستخدم

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

الجديد في Django 1.5، يمكنك الآن إنشاء نموذج المستخدم المخصص الخاص بك (والذي يبدو أنه شيء جيد يجب القيام به في الحالة المذكورة أعلاه).تشير إلى "تخصيص المصادقة في جانغو"

ربما هي أروع ميزة جديدة في الإصدار 1.5.

هذا ما أفعله وهو في رأيي أبسط طريقة للقيام بذلك.حدد مدير الكائنات لنموذجك المخصص الجديد ثم حدد نموذجك.

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

لا تنس إضافة هذا السطر من التعليمات البرمجية في ملفك settings.py:

AUTH_USER_MODEL = 'YourApp.User'

هذا ما أفعله وهو يعمل دائمًا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top