توسيع نموذج المستخدم بالحقول المخصصة في جانغو
-
09-06-2019 - |
المحلول
الطريقة الأقل إيلامًا والموصى بها بالفعل من قبل جانغو للقيام بذلك هي من خلال ملف 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/
باستخدام النهج أعلاه:
- لا تحتاج إلى استخدامuser.get_profile().newattribute للوصول إلى المعلومات الإضافية المتعلقة بالمستخدم
- يمكنك فقط الوصول مباشرة إلى سمات جديدة إضافية عبر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'
هذا ما أفعله وهو يعمل دائمًا.