ویرگول
ورودثبت نام
رضا رضایی
رضا رضاییبرنامه نویس پایتون و توسعه دهنده نرم افزارهای سمت سرور با تخصص در فریمورک جنگو
رضا رضایی
رضا رضایی
خواندن ۸ دقیقه·۲ روز پیش

فصل اول - اپیزود ۶ - ترجمه کتاب Django 5 By Example

فصل اول - اپیزود ۶ ترجمه کتاب Django 5 By Example
فصل اول - اپیزود ۶ ترجمه کتاب Django 5 By Example

ایجاد یک اپلیکیشن

بیایید اولین برنامه جنگو خود را ایجاد کنیم. ما یک برنامهٔ وبلاگ را از ابتدا (از صفر) خواهیم ساخت.

دستور زیر را در shell در دایرکتوری ریشه پروژه (project root directory) اجرا کنید:

python manage.py startapp blog

این دستور ساختار اولیهٔ یک برنامه را ایجاد می‌کند که به شکل زیر خواهد بود:

blog/ ــinitــ.py admin.py apps.py migrations/ ــinitــ.py models.py tests.py views.py

همچنین به تفکیک هرکدام را توضیح خواهم داد:

_init_.py: این یک فایل خالی است و هیچ محتوایی در آن قرار ندارد اما به پایتون نشان میدهد این پوشه(Directory) یک ماژول پایتونی است و این پوشه را به عنوان یک ماژول ببیند.
نکته: در جامعه پایتون به آن داندر اینیت میگویند. به معنی Double Undeline init

admin.py: در این فایل، مدل‌هایی را که می‌خواهید در پنل مدیریت جنگو نمایش داده شوند، ثبت (register) می‌کنید. البته استفاده از این پنل اختیاری است.

apps.py: این فایل حاوی پیکربندی اصلی اپلیکیشن وبلاگ شماست. اینجا جایی است که تنظیمات کلیدی مربوط به این اپلیکیشن خاص تعریف می‌شود.

migrations: این دایرکتوری شامل تغییرات (migrations) مربوط به پایگاه دادهٔ اپلیکیشن شما خواهد بود. Migrations به جنگو این امکان را می‌دهند که تغییرات اعمال شده در مدل‌های شما را پیگیری کرده و پایگاه داده را بر اساس آن‌ها به‌روزرسانی کند. در حال حاضر، این دایرکتوری تنها شامل یک فایل خالی __init__.py است.

models.py: این فایل مدل‌های داده‌ای اپلیکیشن شما را در بر می‌گیرد.
هر اپلیکیشن جنگو نیاز به یک فایل models.py دارد، حتی اگر در ابتدا خالی بماند. این فایل اساس ساختار داده‌ای اپلیکیشن شما را تشکیل می‌دهد.

tests.py: این قسمت جایی است که شما می‌توانید تست‌های خودکار را برای اپلیکیشن‌تان بنویسید تا از صحت عملکرد آن اطمینان حاصل کنید.

views.py: نمایشگرها - منطق اصلی (logic) اپلیکیشن شما در این فایل قرار می‌گیرد. هر نمایشگر(View) یک درخواست HTTP را دریافت می‌کند، آن را پردازش کرده و در نهایت یک پاسخ HTTP را برمی‌گرداند. این فایل قلب تپندهٔ نحوهٔ تعامل کاربر با اپلیکیشن شماست.

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

ایجاد مدل‌های داده برای وبلاگ

به خاطر داشته باشید که یک «شیء» (Object) در پایتون، مجموعه‌ای از داده‌ها (Data) و متدها (Methods) است. «کلاس‌ها» (Classes) در واقع نقشه‌ی ساخت (Blueprint) برای بسته‌بندی این داده‌ها و قابلیت‌ها در کنار یکدیگر را ایفا می‌کنند. ایجاد یک کلاس جدید، باعث ایجاد یک نوع شیء جدید می‌شود که به شما اجازه می‌دهد از آن نوع، «نمونه‌هایی» (Instances) بسازید.

یک مدلِ جنگو (Django Model)، منبعی از اطلاعات درباره‌ی رفتارِ داده‌های شماست. مدل شامل یک کلاس پایتون است که از کلاسِ django.db.models.Model ارث‌بری می‌کند (Subclass می‌کند). هر مدل به یک جدول واحد در پایگاه داده نگاشت (Map) می‌شود؛ به طوری که هر ویژگی (Attribute) از کلاس، نمایانگر یک فیلد (Field) در پایگاه داده است.

وقتی یک مدل ایجاد می‌کنید، جنگو یک رابط برنامه‌نویسی کاربردی (API) کاربردی در اختیار شما قرار می‌دهد تا بتوانید به راحتی روی اشیاء موجود در پایگاه داده، پرس‌وجو (Query) انجام دهید.

ما مدل‌های پایگاه داده را برای اپلیکیشن وبلاگ خود تعریف خواهیم کرد. سپس، برای این مدل‌ها، migrationهای پایگاه داده را تولید می‌کنیم تا جداول مربوطه در دیتابیس ساخته شوند. هنگام اعمال (Apply) کردنِ migrationها، جنگو برای هر مدلی که در فایل models.py اپلیکیشن تعریف شده باشد، یک جدول ایجاد خواهد کرد.

نکته مترجم: وقتی متن می‌گوید کلاس یک Blueprint است، دقیقاً به این اشاره دارد که کلاس فقط یک طرح است و تا زمانی که از آن Instance (با دستور ModelName()) نگیرید، چیزی در حافظه یا دیتابیس وجود ندارد.


ایجاد مدل Post (نوشته)

ابتدا، مدل Post را تعریف می‌کنیم که به ما اجازه می‌دهد پست‌های وبلاگ را در پایگاه داده ذخیره کنیم.

خطوط زیر را به فایل models.py در اپلیکیشن blog اضافه کنید. (خطوط جدید با فونت پررنگ مشخص شده‌اند):

from django.db import models class Post(models.Model): title = models.CharField(max_length=250) slug = models.SlugField(max_length=250) body = models.TextField() def __str__(self): return self.title

این، مدل داده‌ای برای پست‌های وبلاگ است. هر پست دارای یک عنوان (title)، یک برچسب کوتاه به نام slug و یک متن اصلی (body) خواهد بود. بیایید نگاهی به فیلدهای این مدل بیندازیم:

title: این فیلد مربوط به عنوان پست است. این یک فیلد از نوع CharField است که در پایگاه داده‌ی SQL به یک ستون از نوع VARCHAR تبدیل می‌شود.

slug: این یک فیلد از نوع SlugField است که در پایگاه داده‌ی SQL به یک ستون VARCHAR تبدیل می‌شود. اسلاگ (Slug) برچسب کوتاهی است که تنها شامل حروف، اعداد، زیرخط (underscore) یا خط تیره (hyphen) می‌باشد. برای مثال، پستی با عنوان “Django Reinhardt: A legend of Jazz” می‌تواند اسلاگی شبیه به django-reinhardt-legend-jazz داشته باشد. ما در فصل دوم (ارتقای وبلاگ با ویژگی‌های پیشرفته)، از فیلد slug برای ساختن URLهای زیبا و بهینه‌سازی شده برای موتورهای جستجو (SEO-friendly) استفاده خواهیم کرد.

body: این فیلد برای ذخیره‌سازی متن اصلی پست است. این یک فیلد از نوع TextField است که در پایگاه داده‌ی SQL به یک ستون از نوع TEXT تبدیل می‌شود.

همچنین ما یک متد ()__str__ به کلاس مدل اضافه کرده‌ایم. این متد، متد پیش‌فرض پایتون برای بازگرداندن یک رشته (String) است که نمایشی خوانا برای انسان (human-readable) از آن شیء ارائه می‌دهد. جنگو از این متد در بسیاری از بخش‌ها، از جمله در پنل مدیریت جنگو (Django administration site)، برای نمایش نامِ شیء استفاده خواهد کرد.

بیایید نگاهی بیندازیم به اینکه چگونه این مدل و فیلدهای آن، به یک جدول و ستون‌های پایگاه داده تبدیل می‌شوند. نمودار زیر، مدل Post و جدول پایگاه داده متناظر را نشان می‌دهد که جنگو هنگام همگام‌سازی (Synchronize) مدل با پایگاه داده، ایجاد خواهد کرد.

بجنگو برای هر یک از فیلدهای مدل، یعنی title، slug و body، یک ستون در پایگاه داده ایجاد می‌کند. می‌توانید مشاهده کنید که هر نوع فیلد چگونه به یک نوع داده متناظر در پایگاه داده نگاشت می‌شود.

به‌صورت پیش‌فرض، جنگو یک فیلد کلید اصلی (Primary Key) با افزایش خودکار (Auto Increment) به هر مدل اضافه می‌کند. نوع این فیلد در پیکربندی هر برنامه یا به‌صورت سراسری در تنظیم DEFAULT_AUTO_FIELD مشخص می‌شود.

هنگام ایجاد یک برنامه با دستور startapp، مقدار پیش‌فرض DEFAULT_AUTO_FIELD برابر با BigAutoField است. این نوع فیلد یک عدد صحیح ۶۴ بیتی است که به‌طور خودکار و بر اساس شناسه‌های موجود افزایش می‌یابد.

اگر برای مدل خود یک کلید اصلی تعریف نکنید، جنگو این فیلد را به‌صورت خودکار اضافه خواهد کرد. همچنین می‌توانید یکی از فیلدهای مدل را با قرار دادن primary_key=True به‌عنوان کلید اصلی تعریف کنید.

ما مدل Post را با فیلدها و رفتارهای بیشتری گسترش خواهیم داد. پس از تکمیل آن، با ایجاد یک مهاجرت پایگاه داده (Database Migration) و اعمال آن، مدل را با پایگاه داده همگام‌سازی خواهیم کرد.


افزودن فیلدهای تاریخ و زمان (Datetime)

در ادامه، فیلدهای مختلف تاریخ و زمان را به مدل Post اضافه می‌کنیم.

هر پست باید در یک تاریخ و زمان مشخص منتشر شود؛ بنابراین به فیلدی برای ذخیره تاریخ و زمان انتشار نیاز داریم. همچنین می‌خواهیم تاریخ و زمان ایجاد شیء Post و آخرین زمان ویرایش آن را نیز ذخیره کنیم.

فایل models.py برنامه blog را به شکل زیر ویرایش کنید:

from django.db import models from django.utils import timezone class Post(models.Model): title = models.CharField(max_length=250) slug = models.SlugField(max_length=250) body = models.TextField() publish = models.DateTimeField(default=timezone.now) def __str__(self): return self.title

ما یک فیلد publish به مدل Post اضافه کرده‌ایم. این فیلد از نوع DateTimeField است که در پایگاه داده SQL به یک ستون از نوع DATETIME تبدیل می‌شود.

از این فیلد برای ذخیره تاریخ و زمان انتشار پست استفاده خواهیم کرد.

برای مقدار پیش‌فرض این فیلد، از متد timezone.now جنگو استفاده می‌کنیم. توجه کنید که برای استفاده از این متد، ماژول timezone را وارد (import) کرده‌ایم.

متد timezone.now تاریخ و زمان فعلی را به‌صورت آگاه از منطقه زمانی (timezone-aware) برمی‌گرداند. می‌توان آن را نسخهٔ سازگار با منطقه زمانی از متد استاندارد پایتون datetime.now در نظر گرفت.


استفاده از مقدار پیش‌فرض تولیدشده توسط پایگاه داده

روش دیگری برای تعیین مقدار پیش‌فرض فیلدهای مدل، استفاده از مقادیر پیش‌فرض محاسبه‌شده توسط پایگاه داده است.

این قابلیت که در Django 5 معرفی شده است، به شما اجازه می‌دهد از توابع خود پایگاه داده برای تولید مقادیر پیش‌فرض استفاده کنید.

برای مثال:

from django.db import models from django.db.models.functions import Now class Post(models.Model): # ... publish = models.DateTimeField(db_default=Now())

برای استفاده از مقادیر پیش‌فرض تولیدشده توسط پایگاه داده، به‌جای ویژگی default از db_default استفاده می‌کنیم.

در این مثال از تابع پایگاه داده Now استفاده شده است. این تابع کاربردی مشابه default=timezone.now دارد، اما به‌جای اینکه تاریخ و زمان در پایتون تولید شود، از تابع NOW() پایگاه داده برای تولید مقدار اولیه استفاده می‌کند.


حال به نسخه قبلی فیلد برمی‌گردیم:

class Post(models.Model): # ... publish = models.DateTimeField(default=timezone.now)

اکنون فایل models.py را به شکل زیر تکمیل کنید:

from django.db import models from django.utils import timezone class Post(models.Model): title = models.CharField(max_length=250) slug = models.SlugField(max_length=250) body = models.TextField() publish = models.DateTimeField(default=timezone.now) created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) def __str__(self): return self.title

فیلدهای جدید

ما دو فیلد جدید به مدل Post اضافه کرده‌ایم:

created:این فیلد از نوع DateTimeField است. از آن برای ذخیره تاریخ و زمان ایجاد پست استفاده می‌کنیم.

با استفاده از auto_now_add=True، هنگام ایجاد شیء، تاریخ و زمان فعلی به‌طور خودکار در این فیلد ذخیره می‌شود و بعداً تغییر نمی‌کند.

updated:این فیلد نیز از نوع DateTimeField است. از آن برای ذخیره آخرین تاریخ و زمان به‌روزرسانی پست استفاده می‌کنیم.

با استفاده از auto_now=True، هر بار که شیء ذخیره (save) شود، مقدار این فیلد به‌طور خودکار با تاریخ و زمان فعلی به‌روزرسانی می‌شود.

نکته: استفاده از فیلدهای auto_now_add و auto_now در مدل‌های جنگو بسیار مفید است، زیرا به شما امکان می‌دهد زمان ایجاد و آخرین زمان ویرایش اشیاء را بدون نیاز به نوشتن کد اضافی به‌صورت خودکار ردیابی کنید.


پست قبلی: (فصل اول - اپیزود ۵ - تنظیمات پروژه و فایل settings.py)

پست بعدی: (فصل اول - اپیزود ۷ - اضافه کردن ترتیب‌بندی، تنظیم اندیس در پایگاه داده و فعال سازی اپلیکیشن)

معماری نرم افزارآموزش جنگوبرنامه نویسی وب
۲
۰
رضا رضایی
رضا رضایی
برنامه نویس پایتون و توسعه دهنده نرم افزارهای سمت سرور با تخصص در فریمورک جنگو
شاید از این پست‌ها خوشتان بیاید