فصل ۹: مدیریت پنل ادمین (Django Admin) — راهنمای کامل و پیشرفته

""

۱. مقدمه: پنل ادمین چیست و چرا مهم است؟

یکی از ویژگی‌های انقلابی Django که باعث شده خیلی از توسعه‌دهنده‌ها عاشقش بشن، پنل مدیریت (Admin Panel) آماده و قدرتمندشه.
وقتی شما با Django یک Model می‌سازید، ضروری نیست که برای مدیریت داده‌ها از صفر فرم و صفحه بسازید؛ چون Django به صورت پیش‌فرض، بر اساس مدل‌ها، بخشی به نام پنل ادمین رو فراهم می‌کنه که:

  • کاملاً واکنش‌گرا (Responsive) و زیباست.
  • قابلیت افزودن، ویرایش، حذف رکوردهای دیتابیس رو داره.
  • سیستم احراز هویت (Login) داخلی پرقدرت داره.
  • ۱۰۰٪ قابل شخصی‌سازیه؛ می‌تونید ظاهر، امکانات، فیلترها، جستجو و حتی قالب‌ها رو تغییر بدید.

📌 به زبان ساده: با چند خط کد، یک سیستم مدیریت محتوای ساده و امن برای پروژه‌تان دارید.


۲. پیش‌نیازها برای استفاده از Admin

قبل از استفاده باید چند نکته آماده باشه:

۲.۱. فعال بودن اپلیکیشن ادمین

در تنظیمات (settings.py) باید داخل INSTALLED_APPS این‌ها باشه:

INSTALLED_APPS = [
    'django.contrib.admin',        # ماژول اصلی پنل ادمین
    'django.contrib.auth',         # سیستم احراز هویت
    'django.contrib.contenttypes', # برای کار با انواع داده‌ها
    'django.contrib.sessions',     # مدیریت نشست‌ها (sessions)
    'django.contrib.messages',     # سیستم پیام‌رسان داخلی
    'django.contrib.staticfiles',  # مدیریت فایل‌های استاتیک
    # اپلیکیشن‌های خودتان
    'myapp',
]

این ماژول‌ها پیش‌فرض در پروژه‌ها فعال هستن، ولی اگر حذفشون کرده باشید باید برگردونید.


۲.۲. مسیر دسترسی

در urls.py پروژه باید مسیر ادمین تعریف بشه:

from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

این باعث میشه مسیر /admin/ به پنل مدیریتی اشاره کنه.


۲.۳. اجرای مایگریشن‌ها

پنل ادمین برای کار به چند جدول پیش‌فرض نیاز داره (کاربران، گروه‌ها، نشست‌ها). باید این جداول رو بسازیم:

python manage.py migrate

۳. ساخت کاربر مدیر (Superuser)

چون ادمین خصوصی هست، باید یک مدیر درست کنیم:

python manage.py createsuperuser

دستور بالا از شما می‌پرسه:

  • Username → مثل admin
  • Email address → اختیاری
  • Password → باید حداقل ۸ کاراکتر باشه.
    اگر ساده باشه، Django هشدار میده و می‌پرسه آیا مطمئنید.

بعد از ساختن،‌ شما یک کاربر با تمام دسترسی‌ها دارید (وقتی is_staff=True و is_superuser=True).


۴. ورود به پنل ادمین

سرور رو اجرا می‌کنیم:

python manage.py runserver

سپس به آدرس مرورگر:

http://127.0.0.1:8000/admin/

میریم و با نام کاربری و رمز وارد می‌شیم.

نمای پیش‌فرضی بهتون نشون داده میشه که بخش “Authentication and Authorization” رو داره، برای مدیریت کاربران و گروه‌ها.


۵. ثبت مدل‌ها در ادمین (Model Registration)

پنل ادمین فقط مدل‌هایی رو نشون میده که ما ثبتشون کرده باشیم.

فرض کنیم در myapp/models.py داریم:

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200, verbose_name="عنوان")
    content = models.TextField(verbose_name="متن")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="تاریخ ایجاد")

    def __str__(self):
        return self.title

برای نمایش در ادمین (myapp/admin.py):

from django.contrib import admin
from .models import Post

admin.site.register(Post)

حالا وقتی وارد /admin/ بشید، Posts رو می‌بینید.


۶. شخصی‌سازی نمای لیست (List View)

پنل ادمین یک “لیست” از رکوردهای مدل رو نشون میده. این رو میشه سفارشی کرد.

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_display = ('title', 'created_at')  # ستون‌هایی که نمایش داده میشه
    list_filter = ('created_at',)           # فیلتر سمت راست صفحه
    search_fields = ('title', 'content')    # جستجو در این فیلدها
    ordering = ('-created_at',)             # مرتب‌سازی پیش‌فرض

الان:

  • کاربر می‌تونه پست‌ها رو بر اساس تاریخ فیلتر کنه.
  • جستجو بر اساس عنوان و متن فعال شده.
  • آخرین پست‌ها اول میان.

۷. شخصی‌سازی فرم جزئیات (Form View)

وقتی روی یک پست کلیک می‌کنیم، فرم ویرایش باز میشه. میشه فیلدها رو کنترل کرد:

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    fields = ('title', 'content')  # فقط این فیلدها در فرم باشن
    readonly_fields = ('created_at',)  # این فیلد فقط خواندنی باشه

۸. گروه‌بندی فیلدها (Fieldsets)

اگر مدل فیلدهای زیادی داره، می‌تونیم اون‌ها رو گروه‌بندی کنیم:

fieldsets = (
    ('اطلاعات اصلی', {
        'fields': ('title', 'content')
    }),
    ('تاریخ‌ها', {
        'fields': ('created_at',),
        'classes': ('collapse',),  # مخفی شونده
    }),
)

۹. مدیریت مدل‌های مرتبط (Inlines)

اگر مدل دیگری با ForeignKey به مدل اصلی وصل باشه، میشه در همان صفحه مدیریت کرد.

مدل کامنت:

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    author = models.CharField(max_length=100)
    text = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f'نظر {self.author}'

مدل Inline:

class CommentInline(admin.TabularInline):  # جدول‌بندی‌شده
    model = Comment
    extra = 1

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    inlines = [CommentInline]

۱۰. تغییر ظاهر کلی پنل ادمین

بخش بالای ادمین رو میشه تغییر داد:

admin.site.site_header = "پنل مدیریت وبلاگ"
admin.site.index_title = "صفحه اصلی مدیریت"
admin.site.site_title = "بخش ادمین"

۱۱. فیلترهای سفارشی

گاهی لازم داریم فیلتر اختصاصی بسازیم:

from django.utils.translation import gettext_lazy as _

class RecentPostsFilter(admin.SimpleListFilter):
    title = _('پست‌های اخیر')
    parameter_name = 'created_recently'

    def lookups(self, request, model_admin):
        return (
            ('1', _('تازه‌ترین')),
            ('0', _('قدیمی‌تر از یک ماه')),
        )

    def queryset(self, request, queryset):
        from datetime import timedelta, datetime
        from django.utils import timezone

        if self.value() == '1':
            return queryset.filter(created_at__gte=timezone.now() - timedelta(days=30))
        if self.value() == '0':
            return queryset.filter(created_at__lt=timezone.now() - timedelta(days=30))

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_filter = (RecentPostsFilter,)

۱۲. ذخیره خودکار برخی فیلدها

مثلاً میخوای قبل از ذخیره،‌ فیلد author پر بشه:

def save_model(self, request, obj, form, change):
    if not obj.pk:  # رکورد جدید
        obj.author = request.user.username
    super().save_model(request, obj, form, change)

۱۳. بهترین روش‌ها (Best Practices)

  1. محدود کردن دسترسی‌ها
    به همه دسترسی ادمین نده، از سیستم Permissions استفاده کن.
  2. نمایش حداقلی اطلاعات
    زیاد کردن ستون‌ها باعث سنگینی صفحه میشه.
  3. استفاده از Inlines هوشمندانه
    برای ارتباط‌های یک به چند مناسب هست، ولی زیاد بودن رکوردها باعث افت سرعت میشه.
  4. استفاده از verbose_name
    برای فارسی‌سازی و معنای بهتر فیلدها (verbose_name="عنوان").
  5. افزودن str
    همیشه برای مدل‌ها متد __str__ تعریف کن،‌ تا در ادمین نمایش خوانا داشته باشیم.

۱۴. خطاهای رایج

خطاعلتراه‌حل
OperationalError: no such tableمایگریشن انجام نشدهpython manage.py migrate
PermissionDeniedکاربر کارمند (is_staff=True) نیستویرایش کاربر در ادمین و فعال‌کردن تیک Staff
مدل دیده نمیشهثبت نشده در admin.pyثبت با admin.site.register

۱۵. تمرین عملی

🔹 تمرین ۱:
یک اپ store بساز که مدل‌های Product و Category داره.

  • Product شامل: نام، قیمت، دسته‌بندی (ForeignKey).
  • Category شامل: نام.
    مدیریت هر Product رو طوری بساز که لیست محصولات قابل جستجو و فیلتر بر اساس دسته‌بندی باشه.

🔹 تمرین ۲:
یک فیلتر سفارشی برای Product بساز که محصولات ارزان‌تر از ۱۰۰ هزار تومان رو جدا نشون بده.


۱۶. جمع‌بندی

در این فصل یاد گرفتیم:

  • پنل ادمین پیش‌فرض چطور فعال میشه.
  • چطور مدل‌ها رو ثبت کنیم.
  • نمای لیست و جزئیات رو شخصی‌سازی کنیم.
  • مدل‌های مرتبط رو در یک صفحه مدیریت کنیم.
  • فیلتر و جستجوی پیشرفته بسازیم.
  • ظاهر کلی رو تغییر بدیم.
  • نکات امنیتی رو رعایت کنیم.
محمد وب‌سایت

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *