مدلها (Django Models)
مدلها: ساختار دیتابیس شما 📊
مدلها در جنگو کلاسهای پایتونی هستن که ساختار جداول دیتابیس رو تعریف میکنن. جادوی جنگو اینجاست که با تغییر مدلها، جنگو به طور خودکار دیتابیس رو آپدیت میکنه! دیگه نیازی به نوشتن 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 داشته باشه. مایگریتها رو بسازید و اعمال کنید.
تمرینهای عملی
برای تثبیت یادگیری این درس تمرینهای زیر را حل کنید
🎯 تمرین عملی: مدلهای مرتبط
در این تمرین، دو مدل مرتبط میسازیم:
- یک مدل
Categoryبا فیلدهایnameوslug - مدل
Postرو تغییر بدید تا یک فیلدcategoryاز نوعForeignKeyداشته باشه - متد
__str__رو برای هر دو مدل تعریف کنید
راهنمایی: از models.SlugField برای slug و models.ForeignKey برای ارتباط استفاده کنید.
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']
آماده رفتن به درس بعدی هستید؟
این درس را به پایان رساندید و میتوانید به درس بعدی بروید.