🧩 الدرس العاشر: نظام الصلاحيات المتقدم (Roles & Permissions)

  نظام الصلاحيات المتقدم (Roles & Permissions).

Roles & Permissions

🎯 أهداف الدرس

في هذا الدرس سنحوّل نظام الصلاحيات البسيط إلى نظام احترافي يشبه المستخدم في الأنظمة التجارية الكبرى.

سننشئ الأدوار التالية:

👑 Super Admin

يمتلك كامل الصلاحيات:

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

🛡️ Admin

  • إدارة المستخدمين
  • مشاهدة السجلات
  • مشاهدة الإشعارات
  • لا يستطيع إدارة الأدوار العليا

✍️ Editor

  • إضافة وتعديل المحتوى فقط
  • لا يستطيع حذف المستخدمين
  • لا يستطيع إدارة الصلاحيات


🧱 الخطوة 1: إنشاء موديل Role

إذا لم يكن موجوداً سابقاً:

dashboard/models.py

from django.db import models

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

    def __str__(self):
        return self.name

🧱 الخطوة 2: ربط المستخدم بالدور

dashboard/models.py

from django.contrib.auth.models import User

class UserProfile(models.Model):
    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE
    )

    role = models.ForeignKey(
        Role,
        on_delete=models.SET_NULL,
        null=True
    )

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

🧱 الخطوة 3: إنشاء Signal تلقائي

dashboard/signals.py

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

from .models import UserProfile

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

🧱 الخطوة 4: تسجيل Signals

dashboard/apps.py

from django.apps import AppConfig

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

    def ready(self):
        import dashboard.signals

🧱 الخطوة 5: إنشاء Decorators للأدوار

dashboard/decorators.py

from django.shortcuts import redirect

def role_required(role_name):

    def decorator(view_func):

        def wrapper(request, *args, **kwargs):

            if not request.user.is_authenticated:
                return redirect("login")

            profile = request.user.userprofile

            if profile.role and profile.role.name == role_name:
                return view_func(request, *args, **kwargs)

            return redirect("dashboard")

        return wrapper

    return decorator

🧱 الخطوة 6: دعم أكثر من دور

نسخة أقوى:

from django.shortcuts import redirect

def roles_required(allowed_roles):

    def decorator(view_func):

        def wrapper(request, *args, **kwargs):

            if not request.user.is_authenticated:
                return redirect("login")

            role = request.user.userprofile.role

            if role and role.name in allowed_roles:
                return view_func(request, *args, **kwargs)

            return redirect("dashboard")

        return wrapper

    return decorator

🧱 الخطوة 7: حماية الصفحات

صفحة خاصة بالـ Super Admin

@roles_required(["Super Admin"])
def role_management(request):
    return render(
        request,
        "dashboard/roles.html"
    )

صفحة خاصة بالـ Admin

@roles_required([
    "Super Admin",
    "Admin"
])
def users_management(request):
    return render(
        request,
        "dashboard/users.html"
    )

صفحة خاصة بالمحرر

@roles_required([
    "Editor",
    "Admin",
    "Super Admin"
])
def content_management(request):
    return render(
        request,
        "dashboard/content.html"
    )

🧱 الخطوة 8: إنشاء صفحة إدارة الأدوار

dashboard/views.py

from .models import Role

@login_required
@roles_required(["Super Admin"])
def roles_list(request):

    roles = Role.objects.all()

    return render(
        request,
        "dashboard/roles.html",
        {"roles": roles}
    )

🧱 الخطوة 9: قالب عرض الأدوار

templates/dashboard/roles.html

{% extends "dashboard/base.html" %}

{% block content %}

<h2>إدارة الأدوار</h2>

<table class="table table-bordered">

    <thead>
        <tr>
            <th>ID</th>
            <th>Role</th>
        </tr>
    </thead>

    <tbody>

        {% for role in roles %}
        <tr>
            <td>{{ role.id }}</td>
            <td>{{ role.name }}</td>
        </tr>
        {% endfor %}

    </tbody>

</table>

{% endblock %}

🧱 الخطوة 10: إضافة رابط في Sidebar

داخل:

base.html

{% if request.user.userprofile.role.name == "Super Admin" %}
<a href="{% url 'roles_list' %}">
    إدارة الأدوار
</a>
{% endif %}

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

أصبح لدينا:

✅ Super Admin
✅ Admin
✅ Editor
✅ حماية الصفحات حسب الدور
✅ إظهار القوائم حسب الصلاحية
✅ إدارة الأدوار من داخل Dashboard
✅ بنية جاهزة للتوسع


🧪 تمرين الدرس العاشر

قم بإضافة:

Role جديد

Moderator

صلاحياته:

  • مشاهدة المستخدمين
  • مشاهدة السجلات
  • مشاهدة الإشعارات

ولا يستطيع:

  • حذف المستخدمين
  • تعديل الأدوار
  • الوصول للإعدادات

🎯 المطلوب

إنشاء دور:

Moderator

يستطيع:

✅ مشاهدة المستخدمين
✅ مشاهدة سجل النشاطات
✅ مشاهدة الإشعارات

ولا يستطيع:

❌ حذف المستخدمين
❌ تعديل الأدوار
❌ الوصول إلى الإعدادات


🧱 الخطوة 1: إضافة الدور داخل قاعدة البيانات

من Django Shell:

python manage.py shell

ثم:

from dashboard.models import Role

Role.objects.create(
    name="Moderator"
)

🧱 الخطوة 2: تعديل حماية صفحة المستخدمين

في:

views.py

اجعل الصفحة تسمح للـ Moderator بالدخول:

@roles_required([
    "Super Admin",
    "Admin",
    "Moderator"
])
def users_management(request):

    return render(
        request,
        "dashboard/users.html"
    )

🧱 الخطوة 3: حماية صفحة السجلات

@roles_required([
    "Super Admin",
    "Admin",
    "Moderator"
])
def activity_logs(request):

    logs = ActivityLog.objects.all()

    return render(
        request,
        "dashboard/logs.html",
        {"logs": logs}
    )

🧱 الخطوة 4: حماية صفحة الإشعارات

@roles_required([
    "Super Admin",
    "Admin",
    "Moderator"
])
def notifications(request):

    notes = request.user.notifications.all()

    return render(
        request,
        "dashboard/notifications.html",
        {"notes": notes}
    )

🧱 الخطوة 5: منع حذف المستخدمين

في قالب:

users.html

استبدل زر الحذف بـ:

{% if request.user.userprofile.role.name == "Super Admin" or request.user.userprofile.role.name == "Admin" %}

<a href="{% url 'delete_user' user.id %}"
   class="btn btn-danger btn-sm">
    حذف
</a>

{% endif %}

🧱 الخطوة 6: منع إدارة الأدوار

في:

base.html
{% if request.user.userprofile.role.name == "Super Admin" %}
<a href="{% url 'roles_list' %}">
    إدارة الأدوار
</a>
{% endif %}

لن يظهر الرابط للـ Moderator.


🧱 الخطوة 7: منع الوصول للإعدادات

في:

views.py
@roles_required([
    "Super Admin",
    "Admin"
])
def settings_page(request):

    return render(
        request,
        "dashboard/settings.html"
    )

وبذلك لن يستطيع Moderator فتح صفحة الإعدادات حتى لو كتب الرابط يدوياً.


🧱 الخطوة 8: إظهار القوائم حسب الدور

داخل Sidebar:

{% if request.user.userprofile.role.name == "Moderator" %}

<a href="{% url 'users_management' %}">
    المستخدمون
</a>

<a href="{% url 'activity_logs' %}">
    السجلات
</a>

<a href="{% url 'notifications' %}">
    الإشعارات
</a>

{% endif %}

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

الصلاحيةSuper AdminAdminModeratorEditor
إدارة المستخدمين✅✅👁️ فقط❌
حذف المستخدمين✅✅❌❌
إدارة الأدوار✅❌❌❌
السجلات✅✅✅❌
الإشعارات✅✅✅❌
الإعدادات✅✅❌❌
إدارة المحتوى✅✅❌✅

🏆 بعد هذا التمرين

أصبح لديك 4 أدوار كاملة:

  • 👑 Super Admin
  • 🛡️ Admin
  • 🔍 Moderator
  • ✍️ Editor

وهو نفس المفهوم المستخدم في كثير من أنظمة إدارة المحتوى ولوحات التحكم الاحترافية.

تعليقات