دوره‌ها / Django / مدل‌ها (Django Models)

مدل‌ها (Django Models)

35 دقیقه Article

مدل‌ها: ساختار دیتابیس شما 📊

مدل‌ها در جنگو کلاس‌های پایتونی هستن که ساختار جداول دیتابیس رو تعریف می‌کنن. جادوی جنگو اینجاست که با تغییر مدل‌ها، جنگو به طور خودکار دیتابیس رو آپدیت می‌کنه! دیگه نیازی به نوشتن SQL دستی نیست.

ORM چیست؟ جنگو از یک ORM (Object-Relational Mapping) استفاده می‌کنه. یعنی به جای نوشتن SQL، شما با کد پایتون کار می‌کنید و جنگو خودش SQL رو می‌نویسه. این کار خیلی راحت‌تر و امن‌تره!

ساخت یک مدل ساده

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

# blog/models.py
from django.db import models
from django.contrib.auth.models import User

class Post(models.Model):
    # فیلدهای مدل
    title = models.CharField(max_length=200)     # متن کوتاه (حداکثر 200 کاراکتر)
    content = models.TextField()                 # متن بلند (بدون محدودیت)
    author = models.ForeignKey(User, on_delete=models.CASCADE)  # ارتباط با کاربر
    created_at = models.DateTimeField(auto_now_add=True)  # تاریخ ساخت (خودکار)
    updated_at = models.DateTimeField(auto_now=True)      # تاریخ آپدیت (خودکار)
    published = models.BooleanField(default=False)        # آیا منتشر شده؟
    
    # متدهای مدل
    def __str__(self):
        # نمایش مدل در پنل مدیریت
        return self.title
    
    class Meta:
        ordering = ['-created_at']  # مرتب‌سازی بر اساس تاریخ (جدیدترین اول)
        verbose_name = 'پست'
        verbose_name_plural = 'پست‌ها

فیلدهای رایج مدل

انواع فیلدها:

  • CharField: متن کوتاه (نام، عنوان) - نیاز به max_length داره
  • TextField: متن بلند (محتوا، توضیحات) - بدون محدودیت
  • IntegerField: اعداد صحیح (سن، تعداد، قیمت)
  • FloatField: اعداد اعشاری (میانگین، درصد)
  • BooleanField: True/False (فعال/غیرفعال)
  • DateTimeField: تاریخ و زمان
  • EmailField: ایمیل (با اعتبارسنجی خودکار)
  • URLField: آدرس وب (با اعتبارسنجی)
  • ForeignKey: ارتباط یک به چند (مثل یک نویسنده چند پست داره)
  • ManyToManyField: ارتباط چند به چند (مثل یک پست چند تا تگ داره)

مایگریت: اعمال تغییرات

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

# ۱. ساخت فایل‌های مایگریت (Migration)
python manage.py makemigrations

# خروجی: Migrations for 'blog':
#   blog/migrations/0001_initial.py
#     - Create model Post

# ۲. اعمال تغییرات در دیتابیس
python manage.py migrate

# خروجی: Operations to perform:
#   Apply all migrations: blog
# Running migrations:
#   Applying blog.0001_initial... OK
نکته حرفه‌ای: همیشه متد __str__ رو تعریف کنید تا در پنل مدیریت و shell جنگو، نام مناسبی نمایش داده بشه. این کار دیباگ کردن رو خیلی راحت‌تر می‌کنه.
هشدار مهم: هرگز فایل‌های مایگریت رو دستی تغییر ندید مگر اینکه کاملاً مطمئن باشید چیکار می‌کنید! این فایل‌ها توسط جنگو ساخته میشن و تغییر دستی ممکنه باعث خرابی دیتابیس بشه.

کار با مدل‌ها در Python Shell

جنگو یک shell مخصوص داره که مدل‌ها رو به صورت خودکار لود می‌کنه:

# اجرای shell جنگو
python manage.py shell

# در shell:
from blog.models import Post
from django.contrib.auth.models import User

# ساخت یک پست جدید
user = User.objects.first()
post = Post.objects.create(
    title="اولین پست من",
    content="این محتوای پست است",
    author=user,
    published=True
)

# خواندن از دیتابیس
all_posts = Post.objects.all()  # همه پست‌ها
published_posts = Post.objects.filter(published=True)  # فقط پست‌های منتشر شده
first_post = Post.objects.get(id=1)  # پست با id=1

# آپدیت
post.title = "عنوان جدید"
post.save()

# حذف
post.delete()

🎯 تمرین عملی:

یک مدل Category بسازید که شامل name و slug باشه. سپس مدل Post رو تغییر بدید تا یک فیلد category از نوع ForeignKey داشته باشه. مایگریت‌ها رو بسازید و اعمال کنید.

تمرین‌های عملی

برای تثبیت یادگیری این درس تمرین‌های زیر را حل کنید

تمرین: ساخت مدل با ForeignKey Medium
سوال تمرین

🎯 تمرین عملی: مدل‌های مرتبط

در این تمرین، دو مدل مرتبط می‌سازیم:

  1. یک مدل Category با فیلدهای name و slug
  2. مدل Post رو تغییر بدید تا یک فیلد category از نوع ForeignKey داشته باشه
  3. متد __str__ رو برای هر دو مدل تعریف کنید

راهنمایی: از models.SlugField برای slug و models.ForeignKey برای ارتباط استفاده کنید.

پاسخ تمرین
PYTHON
from django.db import models
from django.contrib.auth.models import User

class Category(models.Model):
    name = models.CharField(max_length=100, verbose_name='نام')
    slug = models.SlugField(unique=True, verbose_name='اسلاگ')
    
    def __str__(self):
        return self.name
    
    class Meta:
        verbose_name = 'دسته‌بندی'
        verbose_name_plural = 'دسته‌بندی‌ها'

class Post(models.Model):
    title = models.CharField(max_length=200, verbose_name='عنوان')
    content = models.TextField(verbose_name='محتوا')
    author = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='نویسنده')
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='دسته‌بندی')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='تاریخ ایجاد')
    
    def __str__(self):
        return self.title
    
    class Meta:
        verbose_name = 'پست'
        verbose_name_plural = 'پست‌ها'
        ordering = ['-created_at']

آماده رفتن به درس بعدی هستید؟

این درس را به پایان رساندید و می‌توانید به درس بعدی بروید.