اذهب إلى المحتوى

السؤال

نشر

لدي مستخدم واحد CustomUser ضمن قاعده البيانات ولدي الحقل user_role = models.IntegerField(choices=UserRole.choices, default=UserRole.PATIENT)
الذي يساعدني في تحديد دور المستخدم ضمن الادوار class UserRole(models.IntegerChoices): PATIENT = 1, _('Patient') NURSE = 2, _('Nurse') DOCTOR = 3, _('Doctor')
ولكن واجهتني مشكله انه ظهر لدي حقول اضافيه للادوار الاخرى مثلا دور الممرض يحتوي على التخصص و نشط ام لا و دور الطبيب اريد اضافه التخصص و سعر الكشف والتقيم وغيرها 
هل الافضل ان انشء 3 موديل مختلفين ام هناك حل ؟؟؟ 
models.pymodels.py

بتاريخ الآن قال محمود الخور:

لدي مستخدم واحد CustomUser ضمن قاعده البيانات ولدي الحقل user_role = models.IntegerField(choices=UserRole.choices, default=UserRole.PATIENT)
الذي يساعدني في تحديد دور المستخدم ضمن الادوار class UserRole(models.IntegerChoices): PATIENT = 1, _('Patient') NURSE = 2, _('Nurse') DOCTOR = 3, _('Doctor')
ولكن واجهتني مشكله انه ظهر لدي حقول اضافيه للادوار الاخرى مثلا دور الممرض يحتوي على التخصص و نشط ام لا و دور الطبيب اريد اضافه التخصص و سعر الكشف والتقيم وغيرها 
هل الافضل ان انشء 3 موديل مختلفين ام هناك حل ؟؟؟ 
models.pymodels.py

علما بان كلا منهم له صلاحيات مختلفه في الادمن و سيتم اضافه الممرضين و الاطباء بشكل يدوي من قبل المدير 

Recommended Posts

  • 0
نشر

لا حاجة إلى ذلك، نظام التوثيق في جانغو يعتمد على موديل مستخدم واحد AUTH_USER_MODEL، ولو قمت بإنشاء 3 جداول منفصلة (جدول للمرضى، وجدول للأطباء، وجدول للممرضين) وكل واحد منهم لا يرث من الآخر، ستواجه مشاكل معقدة جداً في تسجيل الدخول، إدارة الجلسات، التصاريح والعلاقات الخارجية مع الجداول الأخرى، فمثلاً من صاحب التعليق؟ هل هو طبيب أم مريض؟

وما قمت بفعله يسمى نمط Profile Pattern، بحيث تحتفظ بالبيانات المشتركة وهي الاسم، الايميل وكلمة المرور في CustomUser، والبيانات الخاصة في جداول مرتبطة.

لكن، لكي تكتمل الصورة وتعمل معك في الـ Admin بشكل احترافي كما طلبت، تحتاج إلى ترتيب ملف admin.py واستخدام الـ Signals لضمان إنشاء البروفايل.

لذا عندما يقوم المدير بإضافة مستخدم وتحديد دوره كطبيب، نريد أن يتم إنشاء DoctorProfile فارغ تلقائيًا حتى لا يحدث خطأ، أي في ملف signals.py أو أسفل models.py أضف التالي:

from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import CustomUser, UserRole, DoctorProfile, NurseProfile, City 

@receiver(post_save, sender=CustomUser)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        if instance.user_role == UserRole.DOCTOR:
            DoctorProfile.objects.create(user=instance, license_number="TBD", specialization="General")
        elif instance.user_role == UserRole.NURSE:
            NurseProfile.objects.create(user=instance, license_number="TBD")

وذكرت أن المدير سيضيفهم بنفسه، وتريد فصلهم وصلاحيات مختلفة، لذا سنستخدم تقنية Proxy Models أي موديل وكيل من خلال إنشاء كلاس وهمي في اسمه DoctorUser وهو ليس بجدول جديد في قاعدة البيانات، بل قناع لجدول CustomUser.

مع Inlines في ملف  admin.py لدمج الحقول في صفحة واحدة وهي طريقة في Django Admin تسمح بوضع نموذج داخل نموذج آخر في نفس الصفحة.

ليصبح في القائمة الجانبية للأدمن Doctors, Nurses, Patients بشكل منفصل، وعند الدخول لإضافة طبيب، ستظهر حقول المستخدم و حقول الطبيب (السعر، التخصص) في نفس الصفحة.

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import CustomUser, DoctorProfile, NurseProfile, UserRole

class DoctorProfileInline(admin.StackedInline):
    model = DoctorProfile
    can_delete = False
    verbose_name_plural = 'Doctor Profile'

class NurseProfileInline(admin.StackedInline):
    model = NurseProfile
    can_delete = False
    verbose_name_plural = 'Nurse Profile'

class CustomUserAdmin(UserAdmin):
    model = CustomUser
    list_display = ['username', 'email', 'user_role', 'is_staff']
    fieldsets = UserAdmin.fieldsets + (
        ('Extra Fields', {'fields': ('user_role', 'city', 'phone', 'date_of_birth', 'image')}),
    )
    add_fieldsets = UserAdmin.add_fieldsets + (
        ('Extra Fields', {'fields': ('user_role', 'city', 'phone', 'date_of_birth', 'image')}),
    )

class DoctorUser(CustomUser):
    class Meta:
        proxy = True
        verbose_name = 'Doctor'
        verbose_name_plural = 'Doctors'

class NurseUser(CustomUser):
    class Meta:
        proxy = True
        verbose_name = 'Nurse'
        verbose_name_plural = 'Nurses'

class DoctorUserAdmin(CustomUserAdmin):
    inlines = [DoctorProfileInline] 
    
    def get_queryset(self, request):
        return super().get_queryset(request).filter(user_role=UserRole.DOCTOR)

    def save_model(self, request, obj, form, change):
        obj.user_role = UserRole.DOCTOR 
        super().save_model(request, obj, form, change)

class NurseUserAdmin(CustomUserAdmin):
    inlines = [NurseProfileInline] 

    def get_queryset(self, request):
        return super().get_queryset(request).filter(user_role=UserRole.NURSE)

    def save_model(self, request, obj, form, change):
        obj.user_role = UserRole.NURSE
        super().save_model(request, obj, form, change)

admin.site.register(CustomUser, CustomUserAdmin) 
admin.site.register(DoctorUser, DoctorUserAdmin) 
admin.site.register(NurseUser, NurseUserAdmin)   

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...