يأتي Django مزودًا بنموذج مستخدم مدمج للمصادقة، ومع ذلك، توصي وثائق Django الرسمية بشدة باستخدام نموذج مستخدم مخصص للمشاريع الجديدة.
هناك طريقتان حديثتان لإنشاء نموذج مستخدم مخصص في جانغو بايثون : AbstractUser
و AbstractBaseUser
.
AbstractBaseUser
يتطلب الكثير والكثير من العمل. لذلك سوف نستخدم AbstractUser
.
سنقوم أيضًا بإنشاء نموذج UserProfile
لتخزين معلومات إضافية حول المستخدمين بمساعدة رابط One-To-One، بعد ذلك، سنقوم بتوسيع وظيفة BaseUserManager
قليلاً.
سنقوم أيضًا بإعداد (signal) لإنشاء ملف UserProfile
تلقائيا عند إنشاء كائن المستخدم. وفي النهاية، سنخصص مدير Django.
ملاحظة: يجب أن نقوم بذلك في بداية المشروع قبل تشغيل أي عمليات ترحيل.
الخطوة 1: تطبيق جديد
قم بإنشاء تطبيق users
باستخدام الأمر python
manage.py
startapp users
قم الآن بتسجيل تطبيقك في تطبيقاتك المثبتة في settings.py:
INSTALLED_APPS += [ 'users', ]
قم بتعيين AUTH_USER_MODEL
في settings.py
على نموذج المستخدم الجديد:
AUTH_USER_MODEL = 'users.User'
الخطوة 2: توسيع النموذج والمدير
قم بإنشاء ملف Constants.py
داخل دليل تطبيق users
.
# users/constants.py
SUPERUSER = 1
STAFF = 2
STUDENT = 3
TUTOR = 4
USER_TYPE_CHOICES = (
(SUPERUSER, 'superuser'),
(STAFF, 'staff'),
(STUDENT, 'student'),
(TUTOR, 'tutor'),
)
قم بتوسيع نموذج User
في users/models.py
.
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils import timezone
from apps.users.managers import UserManager
from . import constants as user_constants
class User(AbstractUser):
username = None # قم بإزالة حقل اسم المستخدم، وسوف نستخدم البريد الإلكتروني كمعرف فريد
email = models.EmailField(unique=True, null=True, db_index=True)
is_active = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now)
user_type = models.PositiveSmallIntegerField(choices=user_constants.USER_TYPE_CHOICES)
REQUIRED_FIELDS = []
USERNAME_FIELD = 'email'
objects = UserManager()
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True,related_name="user_profile")
phone = models.CharField(max_length=255,blank=True,null=True)
is_verified = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.user.email
قم بتوسيع UserManager
في users/managers.py
# users/managers.py
from django.contrib.auth.models import BaseUserManager
from . import constants as user_constants
class UserManager(BaseUserManager):
def create_user(self, email, password, **extra_fields):
if not email:
raise ValueError('The Email must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_active', True)
extra_fields.setdefault('user_type', user_constants.SUPERUSER)
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self.create_user(email, password, **extra_fields)
الخطوة 3:Migrations
قم بتشغيل الأوامر التالية لإجراء تغييرات على قاعدة البيانات
python manage.py makemigrations
python manage.py migrate
الخطوة 4: إنشاء الإشارة
لنقم الآن بإنشاء إشارات لإنشاء مثيل UserProfile
تلقائيًا في users/signals.py
# users/signals.py
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import UserProfile, User
@receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
instance.user_profile.save()
قم بتسجيل ملف الإشارات داخل users/apps.py
عن طريق إضافة تابع جاهز واستيراد مسار ملف الإشارات.
# users/apps.py
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'apps.users'
def ready(self):
import apps.users.signals
بعد ذلك قم بإضافة default_app_config
إلى users/init.py
# users/__init__.py
default_app_config = 'users.apps.UsersConfig'
الخطوة 5: توسيع نموذج المدير
سنقوم الأن بتوسيع UserCreationForm
وUserChangeForm
في users/forms.py
# users/forms.py
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import User
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm):
model = User
fields = ('email',)
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = User
fields = ('email',)
الخطوة 6: تخصيص مستخدم المدير
لنقم بتخصيص مسؤول Django الآن
# users/admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import UserProfile, User
from .forms import CustomUserCreationForm, CustomUserChangeForm
class UserProfileInline(admin.StackedInline):
model = UserProfile
can_delete=False
verbose_plural_name="User Profile"
fk_name = 'user'
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = User
list_display_links = ['email']
search_fields = ('email',)
ordering = ('email',)
# inlines = (UserProfileInline,)
list_display = ('email', 'is_staff', 'is_active', 'is_superuser',)
list_filter = ('email', 'is_staff', 'is_active', 'is_superuser', 'user_type')
fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name', 'email','user_type')}),
(_('Permissions'), {
'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions'),
}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2', 'is_staff', 'is_active', 'user_type')}
),
)
def get_inline_instances(self, request, obj=None):
if not obj:
return list()
return super(CustomUserAdmin, self).get_inline_instances(request, obj)
admin.site.register(User, CustomUserAdmin)
الخطوة 7: التحقق
لقد قمت بتوسيع نموذج المستخدم بنجاح. لنقم الأن بإنشاء مستخدم
python manage.py createsuperuser
#output
Email: develop@pyarab.com
Password: ..........
Password (again): ..........
Superuser created successfully
اكتشاف المزيد من بايثون العربي
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.