🧩 الدرس 4: إنشاء نظام الصلاحيات والأدوار Roles داخل Django Admin Dashboard

نظام الأدوار (Roles) والصلاحيات (Permissions) يعتبر أساس أي لوحة تحكم احترافية، لأنه يحدد ما الذي يستطيع كل مستخدم فعله داخل النظام.

Roles داخل Django Admin Dashboard

في هذا الدرس ستتعلم:

✅ إنشاء أدوار مثل:
Admin – Manager – Editor – Viewer

✅ ربط كل Role بمجموعة Permissions محددة
مثل:

  • إضافة مستخدم
  • حذف مستخدم
  • إنشاء منتج
  • تعديل تقارير
  • عرض Dashboard فقط
  • … إلخ

✅ تطبيق الأدوار على المستخدمين مباشرة
(عندما تختار Role يتم تطبيق صلاحياته تلقائياً).


🎯 أولًا: فهم الصلاحيات في Django

Django يوفر Permissions افتراضية لكل Model:

  • add model
  • change model
  • delete model
  • view model

ويمكنك إضافة صلاحيات مخصصة Custom Permissions أيضًا.


🛠️ الخطوة 1 – إنشاء Model خاص بالأدوار Role

ننشئ موديل جديد يسمى Role في app الرئيسي:

📌 dashboard/models.py

from django.db import models
from django.contrib.auth.models import Permission

class Role(models.Model):
    name = models.CharField(max_length=50, unique=True)
    permissions = models.ManyToManyField(Permission, blank=True)

    def __str__(self):
        return self.name

ثم نعمل ترحيل:

python manage.py makemigrations
python manage.py migrate

🧩 الخطوة 2 – ربط Role بالمستخدم

نضيف ForeignKey لربط المستخدم بدور محدد:

📌 dashboard/models.py

from django.contrib.auth.models import User

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    role = models.ForeignKey(Role, on_delete=models.SET_NULL, null=True, blank=True)

    def __str__(self):
        return self.user.username

إنشاء profile تلقائيًا عند إنشاء User (Signal):

📌 dashboard/signals.py

from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

فعل signals داخل apps.py.


🔒 الخطوة 3 – تطبيق صلاحيات الدور تلقائيًا عند تعيينه للمستخدم

نضيف دالة تمنح المستخدم جميع الصلاحيات المرتبطة بالـRole:

📌 dashboard/models.py

def apply_role_permissions(self):
    if self.role:
        self.user.user_permissions.set(self.role.permissions.all())
        self.user.save()

نستدعيها في كل تعديل Role داخل Profile:

📌 dashboard/signals.py

@receiver(post_save, sender=Profile)
def update_user_permissions(sender, instance, **kwargs):
    instance.apply_role_permissions()

🎛️ الخطوة 4 – واجهة إدارة الأدوار داخل Django Admin

نسجل Role و Profile في لوحة التحكم:

📌 dashboard/admin.py

from django.contrib import admin
from .models import Role, Profile

class RoleAdmin(admin.ModelAdmin):
    filter_horizontal = ('permissions',)

admin.site.register(Role, RoleAdmin)
admin.site.register(Profile)

سيظهر لك:

✓ إنشاء دور جديد
✓ إضافة صلاحيات إليه
✓ ربطه بالمستخدمين


🧩 الخطوة 5 – حماية الصفحات بناء على الـPermissions

مثال: صفحة يمكن للمدير فقط الدخول إليها:

📌 dashboard/views.py

from django.contrib.auth.decorators import permission_required

@permission_required('auth.view_user', raise_exception=True)
def manage_users(request):
    return render(request, 'dashboard/manage_users.html')

مثال آخر:
السماح لمن لديه Role Editor فقط:

def is_editor(user):
    return hasattr(user, 'profile') and user.profile.role.name == "Editor"

@user_passes_test(is_editor)
def editor_page(request):
    return render(request, 'dashboard/editor_only.html')

🎉 النتيجة النهائية

من خلال هذا الدرس أصبح لديك:

⭐ نظام Roles احترافي
⭐ تخصيص صلاحيات وتطبيقها تلقائيًا
⭐ حماية الصفحات بناءً على role أو permission
⭐ تعامل كامل مع Django Auth System


✅ حل التمرين — إنشاء نظام Roles وصلاحيات داخل Django

المطلوب في التمرين كان:

1-إنشاء دورين:

  • Admin
  • Editor

2-جعل Admin لديه كامل الصلاحيات.

3- جعل Editor يستطيع:

  • الدخول للوحة التحكم
  • تعديل المحتوى
  • لكن لا يستطيع حذف أي شيء
  • ولا يستطيع إدارة المستخدمين

4- سنقوم الآن بالحل:


🎯 خطوة 1 — إنشاء المجموعات (Groups)

افتح ملف
dashboard/admin_setup.py
(يمكنك تسميته كما تريد، المهم استدعاؤه في ready())

admin_setup.py

from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.apps import apps

def create_roles():
    # التحقق حتى لا يتم التكرار
    if Group.objects.filter(name="Admin").exists():
        return
    
    # إنشاء المجموعتين
    admin_group = Group.objects.create(name="Admin")
    editor_group = Group.objects.create(name="Editor")

    # جلب كل الصلاحيات
    all_permissions = Permission.objects.all()

    # إضافة كل الصلاحيات للـ Admin
    admin_group.permissions.set(all_permissions)

    # صلاحيات Editor (عرض + تعديل فقط)
    permitted_codenames = [
        "view_post", "change_post",   # لو كان لديك موديل Post
        "view_category", "change_category"
    ]

    # إضافة الصلاحيات المحددة
    perms = Permission.objects.filter(codename__in=permitted_codenames)
    editor_group.permissions.set(perms)

    print("Roles created successfully!")

🎯 خطوة 2 — تشغيل الدالة تلقائيًا عند تشغيل Django

نفتح ملف apps.py داخل تطبيق Dashboard

apps.py

from django.apps import AppConfig

class DashboardConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'dashboard'

    def ready(self):
        from .admin_setup import create_roles
        try:
            create_roles()
        except:
            pass

🎯 خطوة 3 — ربط المستخدم بدور (Group)

يمكنك داخل الـ Django Admin اختيار المستخدم ومن قسم Groups تضيفه إلى:

  • Admin
  • أو Editor

أو يمكنك برمجيا:

from django.contrib.auth.models import User, Group

user = User.objects.get(username="tamer")
editor_group = Group.objects.get(name="Editor")
user.groups.add(editor_group)

🎯 خطوة 4 — منع Editor من الحذف داخل الـ Admin

في ملف admin.py الخاص بالموديل:

مثلاً لموديل Post:

from django.contrib import admin
from .models import Post

class PostAdmin(admin.ModelAdmin):
    def has_delete_permission(self, request, obj=None):
        # منع Group Editor من الحذف
        if request.user.groups.filter(name="Editor").exists():
            return False
        return True

admin.site.register(Post, PostAdmin)

🎯 النتيجة النهائية

الدور الصلاحيات
Admin وصول كامل لجميع أجزاء اللوحة
Editor عرض وتعديل المحتوى فقط — ❌ بدون حذف — ❌ بدون إدارة مستخدمين
تعليقات