طراحی مدل دیتابیس جنگو
تو این آموزش قراره با نحوه طراحی مدل دیتابیس جنگو آشنا بشیم.
پس میریم که اولین مدل مورد نیاز برای اپلیکیشن وبلاگ جنگوی خودمون رو بسازیم.
طراحی شمای داده(دیتابیس) وبلاگ
فریمورک جنگو از ORM یا همون Object Relational Model استفاده میکنه. (بزودی تو یه مطلب جداگونه راجع به اینکه Django ORM چیه صحبت خواهم کرد)
برای اینکه بخوایم شمای دیتابیس مون رو برای استفاده توی اپلیکیشن blog طراحی کنیم، باید بیایم و data model بسازیم. Model در حقیقت یه کلاس پایتون هستش که از زیر مجموعه های django.db.models.Model هستش که توی اون هر اتریبیوت، نمایشگر یه فیلد دیتابیسه.
جنگو برای هر مدلی که توی فایل models.py تعریف شده باشه بصورت خودکار به جدول توی دیتابیس میسازه. وقتی هم که مدل مورد نظرتون رو ساختین، دیگه به راحتی میشه توسط سیستم ORM جنگو، اقدامات مورد نیازتون رو روی دیتابیس انجام بدید.
پس اولین کاری که باید بکنیم اینه که بیایم داخل فایل models.py و یه مدل Post که قراره جدول مربوط به پست ها رو برامون ایجاد کنه بسازیم:
from django.db import models from django.utils import timezone from django.contrib.auth.models import User class Post(models.Model): STATUS_CHOICES = ( ('draft', 'Draft'), ('published', 'Published'), ) title = models.CharField(max_length=250) slug = models.SlugField(max_length=250, unique_for_date='publish') author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts') body = models.TextField() publish = models.DateTimeField(default=timezone.now) created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft') class Meta: ordering = ('-publish',) def __str__(self): return self.title
خب حالا این شما و این هم مدل Post که برای نگهداری پست های وبلاگمون ساختیم. بیاین یه نگاه بندازیم ببینیم اینجا چه خبره:
- title: عنوان مطلب رو اینجا نگه میداریم. از نوع CharField هستش که توی دیتابیس SQL بصورت VARCHAR شناخته میشه. Max_length یعنی حداکثر چند کاراکتر بتونه توی این فیلد قرار بگیره. ( که اینجا گفتیم حداکثر 250 کاراکتر)
- slug: توی این فیلد میخوایم آدرس URL مطلبمون رو نگهداری کنیم. SlugField بصورت پیشفرض فقط میتونه شامل حروف، اعداد، آندرلاین و خط تیره بشه (برای اینکه بتونیم url های با زبان فارسی داشته باشیم نیاز به یه سری تغییرات جزئی داریم که بعداً با هم میبینیم). در اینجا از پارامتر unique_for_date استفاده کردیم که باعث میشه url هایی که برای مطالبمون ساخته میشن بر اساس زمان انتشارشون و بصورت مجزا از سایر مطالب ساخته شده باشن که از تکرار url ها جلوگیری بشه.
- author: این فیلد، کلید خارجی ما (Foreign Key) هستش. یعنی توسط این فیلد میایم و یه ارتباط many-to-one با یه User(که قراره به عنوان نویسنده مطلب باشه) برقرار میکنیم. چرا از many-to-one استفاده کردیم؟ چون در اینجا فلسفه مون اینه که هر مطلب توسط یک user نوشته شده، و همینطور هر user میتونه هر چندتا مطلب که میخواد بنویسه. به این صورت که اینجا نوشتیم، جنگو میاد بر مبنای کلید اصلی ای که ایجاد کردیم، یه foreign key توی دیتابیس میسازه. اینجا، ما از مدل User که جزو سیستم پیشفرض authentication جنگو هستش استفاده کردیم. پارامتر on_delte مشخص میکنه که اگر یه author حذف شد، دیتابیس بیاد چیکار کنه. چیزی که اینجا تعریف کردیم اینه که میگیم بیا اگر author پاک شد(یعنی اگر یه User که یه مطلبی رو نوشته بود، پاک شد) همه مطالبی رو که اون User نوشته رو هم پاک کن! موارد دیگه ای هم داره که میتونید از اینجا مطالعه کنید:
https://docs.djangoproject.com/en/3.0/ref/models/fields/#django.db.models.ForeignKey.on_delete
در نهایت با مشخص کردن related_name هم داریم میگیم که بیا اسم فیلدی که قراره author و User از طریقش با هم ارتباط داشته باشن رو با این اسم بساز. (بعداً بیشتر باهاش آشنا میشیم.)
- body: متن اصلی مطلب ما در این قسمت قرار خواهد گرفت. مقادیر را بصورت TEXT در این فیلد ذخیره خواهیم کرد.
- publish: این فیلد زمان منتشر شدن مطلب را مشخص میکند. در اینجا مشخص کرده ایم که بصورت پیشفرض زمان لحظه را در نظر بگیرد.
- created: توسط این فیلد، زمان ساخت مطلب را ذخیره خواهیم کرد. با استفاده از auto_now_add=True، در زمان ساختن یک مطلب، تاریخ کامل بصورت اتوماتیک در این فیلد ذخیره میشود.
- updated: مشابه فیلد بالا میباشد. فقط در اینجا با استفاده از auto_now تاریخ بروزرسانی شدن مطلب را در این فیلد ذخیره میکنیم.
- status: با تعریف این فیلد در دیتابیس، وضعیت یک مطلب را مشخص میکنیم. در اینجا از پارامتر choices استفاده کرده ایم که به ما کمک میکند تا مقادیر مورد نیاز(مثلاً: پیشنویس، منتشر شده، و …) را ذخیره و انتخاب کنیم.
در فریمورک جنگو، انواع گوناگونی از فیلدها قابل استفاده هستند که میتونید از اینجا مشاهده کنید:
https://docs.djangoproject.com/en/3.0/ref/models/fields/
کلاس Meta که در اینجا در مدل نوشتیم، شامل یک سری metadata هستش. یعنی چی؟
یعنی اینکه مثلاً در اینجا، با استفاده از کلاس Meta میایم و به جنگو میگیم که بیا وقتی یه کوئری روی دیتابیس زدیم، بصورت پیشفرض بر اساس فیلد publish برامون سورت نزولی رو انجام بده.( و اگر هم قبل از اسم فیلد، شکلک خط تیره بذارید، میاد و برعکس اون عملیات رو انجام میده و آخرین مطلب منتشر شده رو در جایگاه اول برامون نمایش میده)
در نهایت با استفاده از متد ()__str__ به جنگو میگیم که برامون چه نوشته ای رو نمایش بده(پیشنهاد میکنم برای اینکه بهتر متوجه بشید، یه دور بدون این متد پیادهسازی کنین مدل رو، و بعد که دیدید شکل اولیه رو، این متد رو قرار بدید تا تفاوت رو مشاهده کنین)
ساخت و migrate کردن جداول دیتابیس
خب، تا اینجای کار اومدیم و data model مون رو برای مطالب وبلاگمون ایجاد کردیم. حالا باید بیایم و این data model ها رو به جداول دیتابیس تبدیل کنیم. جنگو برای این کار، یه سیستم migration داره که همه تغییراتی که روی مدل ها اعمال کردیم رو دنبال میکنه و آماده شون میکنه تا بتونیم ببریمشون توی دیتابیس.
همونطور که قبلتر هم اشاره کردیم، با استفاده از دستور migrate میتونیم همه migration های موجود برای اپلیکیشن های لیست شده توی INSTALLED_APP رو با دیتابیس سینک کنیم و به پایگاه داده مون منتقل کنیم.
برای اینکار اول باید برای مدل Post یه migration بسازیم:
python manage.py makemigrations blog
همچین خروجی ای رو مشاهده خواهید کرد:
Migrations for 'blog': blog\migrations\0001_initial.py - Create model Post
حالا همونطور که میبینید، جنگو در دایرکتوری blog/migrations یه فایل با اسم 0001_initial.py ساخته که میتونید داخلش رو نگاه کنید تا ببینید که چه چیزهایی رو قراره اجرا بکنه.( عملیات سینک کردن دیتابیس با مدل های ما توسط کدهای موجود در این فایل داره انجام میشه )
نکته اضافه: اگر بخواین ببینید که کد SQL ای که جنگو برای ساختن جدول از مدلی که ساختیم اجرا میکنه چی هستش میتونید کد زیر رو توی کنسول ترمینالتون وارد کنید:
python manage.py sqlmigrate blog 0001
خب در گام بعدی، برای اینکه دیتابیس با مدل ساخته شده سینک بشه و بتونیم جدول مورد نظرمون رو بسازیم، دستور زیر را اجرا میکنیم:
python manage.py migrate
خروجی بصورت زیر خواهد شد:
Applying blog.0001_initial... OK
تبریک میگم! 🙂
همین حالا با موفقیت جدول Post رو توی دیتابیس ساختین.
فقط حتماً مد نظر داشته باشید هر زمان که تغییراتی روی فیلدهای موجود در فایل models.py بدید یا مثلاً یه مدل جدید بهش اضافه کنید، باید اول makemigrations کنید و بعدش که فایل migrate براتون ساخته شد، میتونید با دستور migrate تغییرات رو روی دیتابیستون اعمال کنید.
تو این مطلب اولین مدلمون برای ذخیره مطالب رو با اسم Post ساختیم. و بعد از اون اومدیم فایل migration مورد نیاز رو آماده کردیم و در نهایت هم جدول Post رو توی دیتابیس جنگو ساختیم.
در قسمت بعدی پنل ادمین جنگو رو فعال میکنیم.
تو آموزش های بعدی مرکز تخصصی آموزش جنگو، کلی مباحث مختلف و خوب داریم که بتونید هرچی بیشتر با مباحث فریمورک قدرتمند جنگو آشنا بشید و یادشون بگیرید.
سوالات و نظراتتون رو هم حتماً حتماً با ما در میون بذارید.
دیدگاهتان را بنویسید