گسترش دادن user model در Django

با نام خدا وسلام، خب تو این آموزش میخوام یه مقدار در مورد user model در django صحبت کنم. user model  به صورت پیش فرض با توجه به اسناد خود django دارای فیلد های زیر هست:

حال اگر بخواهیم علاوه بر این موارد بالا فیلد های دیگری نیز داشته باشیم و از user model و authenticationخود django  نیز استفاده کنیم، باید یه کارایی انجام بدیم.

خب مرجع اصلی این مطلبی که به اشتراک گذاشتم سایت اسناد django که در بالا نیز یه بار بهش ارجاع دادم. با توجه به این مرجع دو راه برای گسترش دادن مدل پیشفرض User  بدون استفاده از یک مدل جدید وجود دارد.

اگر تغییرات مورد نظر صرفا behavioral هستند و روی داده هایی که در پایگاه داده ذخیره می شوند کاری ندارند، می تونید با ساخت یک proxy model بر مبنای User ، مشکل خودتان را حل کنید. این کار اجازه ی استفاده از تمامی ویژگی های ارایه شده در proxy model شامل ordering ، custom manager ها یا متد های custom model می باشد.

اگر قصد دارید که اطلاعات مرتبط با User را ذخیره نمایید ، می توانید از OneToOneField داخل مدلی که دارای فیلد های مورد نظر شما است استفاده کنید. به این one-to-one model معمولا profile model نیز گفته می شود. برای مثال Employee model :

from django.contrib.auth.models import User

class Employee(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    department = models.CharField(max_length=100)

حال فرض کنید یک user  با نام Fred Smith داریم، که هر جفت مدل های User  و  Employee را نیز دارد، به طریق زیر می توان به اطلاعاتش دسترسی پیدا کرد:

>>> u = User.objects.get(username='fsmith')
>>> freds_department = u.employee.department

حال برای اضافه کردن فیلد های profile model به صفحه user  در admin، یک InlineModelAdmin درون admin.py داخل app خودتون باید تعریف کنید (باری نمونه از StackedInlineاستفاده کردیم) و به کلاس UserAdmin که توسط کلاس User  ثبت شده نیز اضافه اش کنید:

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User

from my_user_profile_app.models import Employee

# Define an inline admin descriptor for Employee model
# which acts a bit like a singleton
class EmployeeInline(admin.StackedInline):
    model = Employee
    can_delete = False
    verbose_name_plural = 'employee'

# Define a new User admin
class UserAdmin(BaseUserAdmin):
    inlines = (EmployeeInline, )

# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)

خب این روش کار راه بیانداز هست اما بهترین روش نیست، بهترین روش ساخت User برای خودمان با فیلدهای خودمان و همچنین ارث بری از ویژگی های authenticationخود django هست که یه مقدار بحث پیچیده تری میشه. ولی در مودرش حرف خواهم زد.