فصل ۱۶ — Permissions & Groups در Django (مدیریت سطح دسترسی کاربران)

۱. مقدمه — چرا مجوزها مهم هستند؟
هر وبسایت یا اپلیکیشن حرفهای نیاز داره که بعضی بخشها یا عملیاتش رو فقط کاربرانی با نقش خاص انجام بدن.
در سناریوی فروشگاه آنلاین:
- فقط ادمین میتونه محصول اضافه یا حذف کنه
- مدیر انبار میتونه موجودی محصولات رو تغییر بده ولی حق حذف نداره
- کاربر عادی فقط میتونه محصولات رو ببینه و سفارش بده
Permission = اجازه انجام یک کار خاص
Group = مجموعهای از مجوزها که به یک دسته کاربران داده میشه
۲. سیستم مجوز داخلی Django
Django بهصورت پیشفرض:
- برای هر مدل سه مجوز اصلی ایجاد میکنه:
add_modelnamechange_modelnamedelete_modelname
و از نسخههای جدید:view_modelnameهم اضافه شده.
یعنی اگه مدل Product داشته باشیم:
add_productchange_productdelete_productview_product
۳. بررسی مجوز یک کاربر
if request.user.has_perm('app_name.add_product'):
# کاربر اجازه اضافه کردن محصول را دارد
else:
# بدون اجازه
📌 نکته: ساختار has_perm → "ناماپ.ناممجوز"
۴. اضافه کردن مجوز سفارشی به مدل
گاهی نیاز داریم علاوه بر مجوز پیشفرض، مجوزهای ویژه تعریف کنیم.
models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
class Meta:
permissions = [
("can_discount", "امکان اعمال تخفیف روی محصول"),
]
بعد از makemigrations و migrate، مجوز جدید در دیتابیس ایجاد میشه.
۵. اختصاص مجوز به کاربر
این رو میشه هم از طریق Admin Panel انجام داد هم کدنویسی.
نمونه کدنویسی
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from .models import Product
content_type = ContentType.objects.get_for_model(Product)
permission = Permission.objects.get(codename='can_discount', content_type=content_type)
user.user_permissions.add(permission)
۶. استفاده از @permission_required
برای حفاظت از ویوها، میشه از دکوراتور permission_required استفاده کرد.
from django.contrib.auth.decorators import permission_required
@permission_required('app_name.can_discount', raise_exception=True)
def discount_product(request, pk):
# کد تخفیف محصول
pass
📌 raise_exception=True → به جای ریدایرکت، خطای 403 برمیگردونه.
۷. مدیریت مجوز در CBV (Class-based Views)
در CBV باید از PermissionRequiredMixin استفاده کنیم.
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.views.generic import UpdateView
from .models import Product
class ProductDiscountView(PermissionRequiredMixin, UpdateView):
model = Product
fields = ['price']
template_name = 'product_discount.html'
success_url = '/products/'
permission_required = 'app_name.can_discount'
۸. Group — گروههای کاربری
گروهها برای دادن چندین مجوز به چند کاربر به صورت یکجا عالی هستند.
مثال:
- گروه مدیر فروش
- گروه مدیر انبار
- گروه کاربر VIP
ایجاد گروه
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from .models import Product
# ساخت گروه
group, created = Group.objects.get_or_create(name="Store Manager")
# اختصاص مجوز اضافه کردن و تغییر محصول به گروه
content_type = ContentType.objects.get_for_model(Product)
perms = Permission.objects.filter(content_type=content_type, codename__in=['add_product', 'change_product'])
group.permissions.add(*perms)
۹. اضافه کردن کاربر به گروه
group = Group.objects.get(name="Store Manager")
user.groups.add(group)
۱۰. بررسی عضویت در گروه
if request.user.groups.filter(name="Store Manager").exists():
# کاربر عضو این گروهه
۱۱. محدود کردن دسترسی به گروه در CBV
from django.contrib.auth.mixins import UserPassesTestMixin
class StoreManagerView(UserPassesTestMixin, ListView):
model = Product
template_name = 'products.html'
def test_func(self):
return self.request.user.groups.filter(name="Store Manager").exists()
۱۲. ترکیب Permission و LoginRequired
اغلب باید این دو رو با هم استفاده کنیم:
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
class ProductCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
model = Product
fields = ['name', 'price']
permission_required = 'app_name.add_product'
template_name = 'product_form.html'
success_url = '/products/'
۱۳. سناریوی عملی — فروشگاه
نقشها:
- Admin → همه مجوزها
- Store Manager → اضافه و ویرایش محصول
- Inventory Staff → فقط تغییر تعداد موجودی
- Customer → مشاهده محصولات و خرید
📌 این ساختار باعث میشه مدیریت سایت خیلی منعطف باشه.
۱۴. نکات پیشرفته و حرفهای
- همیشه قبل از عملیات حساس (مثل حذف) یک لایه اضافی کنترل مجوز بگذار
- برای مجوزهای زیاد از Groups استفاده کن، نه دسترسی مستقیم به هر کاربر
- با سیگنال
post_saveمیتونی به کاربران جدید به صورت پیشفرض یک گروه بدی - از
Object-level Permissions(با پلاگینهایی مثل django-guardian) برای کنترل دسترسی به رکورد خاص استفاده کن
۱۵. خطاهای رایج
| خطا | علت |
|---|---|
PermissionDenied | کاربر مجوز ندارد یا لاگین نکرده |
| مجوز اعمال نمیشه | نام مجوز را اشتباه وارد کردی |
| گروه ساخته میشه ولی کار نمیکنه | مجوزها به گروه اضافه نشده یا کاربر عضو گروه نیست |
جمعبندی فصل ۱۶
ما اینجا یاد گرفتیم:
- مجوزهای پیشفرض Django و نحوه بررسیشون
- ساخت مجوز سفارشی
- استفاده در FBV و CBV
- ایجاد گروه و اختصاص مجوز به آن
- سناریوی واقعی فروشگاه با نقشهای مختلف
- نکات امنیتی و بهترین روشها