پروژه بلاگ با جنگو
اولین پروژهای که با جنگو میسازید، یک blog application خواهد بود. این پروژه به شما کمک میکند تا با تواناییها و امکانات اصلی Django بهخوبی آشنا شوید.
وبلاگ بهترین نقطهی شروع برای یادگیری Django است، چون امکانات متنوعی نیاز دارد؛ از مدیریت محتوای ساده گرفته تا قابلیتهای پیشرفته مثل commenting، post sharing، search و post recommendations. در سه فصل اول این کتاب، روی همین پروژه کار خواهیم کرد.
در این فصل، ابتدا یک Django project و یک Django application برای وبلاگ میسازیم. سپس data models را طراحی میکنیم و آنها را با database هماهنگ میکنیم. در ادامه، یک administration site برای وبلاگ راهاندازی میکنیم و بعد سراغ ساخت views، templates و URLs میرویم.
در عکس1.2 تصویری از صفحاتی که قرار است برای blog application بسازید، نشان داده شده است.
برنامه blog application شامل یک لیست از posts خواهد بود که در آن عنوان پست(post title), تاریخ انتشار(publishing date)، نویسنده (author)، یک post excerpt و لینکی برای خواندن پست نمایش داده میشود. صفحهی لیست پستها با استفاده از post_list view پیادهسازی خواهد شد. در این فصل یاد میگیرید که چگونه views ایجاد کنید.
وقتی خوانندگان روی لینک یک پست در صفحهی لیست پستها کلیک کنند، به یک single (detail) view از آن پست منتقل میشوند. در تاریخ انتشار و عنوان نویسنده و متن کامل پست نمایش داده خواهد شد.
بیایید با ایجاد یک Django project برای وبلاگ کار خود را آغاز کنیم. Django دستوری در اختیار شما قرار میدهد که به کمک آن میتوانید ساختار اولیه فایلهای پروژه را ایجاد کنید.
این دستور را در shell prompt اجرا کنید:
django-admin startproject mysite
این دستور یک پروژه جنگو با نام mysite ایجاد خواهد کرد.
از نامگذاری پروژهها با نام Python modules یا Django modules داخلی خودداری کنید تا از ایجاد تداخل جلوگیری شود.
حال بیایید نگاهی به ساختار پروژهی ایجادشده بیندازیم:
mysite/
manage.py
mysite/
__init__.py
asgi.py
settings.py
urls.py
wsgi.py
برای تغییر این متن بر روی دکمه ویرایش کلیک کنید. لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است.
manage.py: یک ابزار خط فرمان است که برای تعامل با پروژه استفاده میشود. معمولاً نیازی به ویرایش این فایل نخواهید داشت.
mysite/: این پوشه Python package پروژه است و شامل فایلهای زیر میباشد:
- __init__.py: یک فایل خالی که به Python اعلام میکند پوشهی mysite یک Python module است.
- asgi.py: تنظیمات اجرای پروژه به صورت یک ASGI application با وبسرورهای سازگار با ASGI. (ASGI استاندارد جدید Python برای وبسرورها و برنامههای asynchronous است.)
- settings.py: شامل تنظیمات و پیکربندیهای پروژه است و مقادیر پیشفرض اولیه را در خود دارد.
- urls.py: جایی است که URL patterns تعریف میشوند. هر URL در اینجا به یک view متصل میشود.
- wsgi.py: تنظیمات اجرای پروژه به صورت یک WSGI application با وبسرورهای سازگار با WSGI.
اعمال مایگریشنهای اولیه دیتابیس
برنامههای جنگو برای ذخیره دادهها به یک دیتابیس نیاز دارند. فایل settings.py شامل تنظیمات دیتابیس پروژه در بخش DATABASES است.که بهطور پیشفرض، یک دیتابیس SQLite3 تنظیم شده است.
SQLite همراه با Python 3 ارائه میشود و میتوان آن را در هر برنامهی Python استفاده کرد. این دیتابیس سبک است و میتوانید از آن برای توسعه پروژههای Django استفاده کنید. اما اگر قصد دارید برنامه را در یک محیط production اجرا کنید، بهتر است از یک دیتابیس کاملتر مثل PostgreSQL، MySQL یا Oracle استفاده کنید. اطلاعات بیشتر دربارهی راهاندازی دیتابیس با Django را میتوانید در این صفحه پیدا کنید
فایل settings.py همچنین لیستی به نام INSTALLED_APPS دارد که شامل چند برنامهی عمومی Django است که به صورت پیشفرض به پروژه اضافه میشوند. در بخش تنظیمات پروژه به این برنامهها بیشتر میپردازیم.
برنامههای جنگو شامل data models هستند که به جدول دیتابیس متصل میشوند. شما در بخش ساخت دیتامدل، مدلهای خود را ایجاد خواهید کرد. برای تکمیل راهاندازی پروژه، لازم است جداول مربوط به مدلهای برنامههای پیشفرض Django که در INSTALLED_APPS تعریف شدهاند ایجاد شوند. جنگو سیستمی دارد که به شما کمک میکند تا این database migrations را مدیریت کنید.
cd mysite
python manage.py migrate
شما خروجیای خواهید دید که در انتها شامل خطوط زیر است:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
خطوطی که در خروجی دیدید مربوط به database migrations هستند که توسط Django اعمال شدهاند. با اجرای مایگریشنهای اولیه، جداول مربوط به برنامههایی که در INSTALLED_APPS تعریف شدهاند در دیتابیس ایجاد میشوند.
در بخش Creating and applying migrations از این فصل، بیشتر با دستور مدیریتی migrate آشنا خواهید شد.
اجرای سرور توسعه (Development Server) در جنگو
جنگو همراه با یک وب سرور سبک ارائه میشود تا بتوانید کدهای خود را به سرعت اجرا کنید، بدون اینکه نیاز به پیکربندی یک سرور production داشته باشید.
وقتی سرور توسعهی Django را اجرا میکنید:
بهطور مداوم تغییرات کد شما را بررسی میکند.
به صورت خودکار reload میشود و نیازی نیست بعد از هر تغییر، آن را دستی راهاندازی کنید.
البته بعضی تغییرات مانند اضافهکردن فایلهای جدید ممکن است شناسایی نشوند؛ در این موارد باید سرور را به صورت دستی restart کنید.
برای اجرای سرور توسعه، دستور زیر را در shell prompt وارد کنید:
python manage.py runserver
باید خروجیای مشابه زیر ببینید:
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
August 16, 2025 - 13:15:40
Django version 5.0.14, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
حالا آدرس http://127.0.0.1:8000/ را در مرورگر خود باز کنید. باید صفحهای ببینید که نشان میدهد پروژه با موفقیت در حال اجرا است، همانطور که در Figure 1.3 نمایش داده شده است.
تصویر بالا نشان میدهد که Django در حال اجرا است. اگر به کنسول یا ترمینال خود نگاه کنید، درخواست GET که توسط مرورگر شما ارسال شده است را مشاهده خواهید کرد:
[01/Jan/2024 10:00:15] "GET / HTTP/1.1" 200 16351
هر درخواست http توسط سرور جنگو در console ثبت میشود. همچنین هر خطایی که هنگام اجرای سرور توسعه رخ دهد در console نمایش داده خواهد شد.
میتوانید سرور جنگو را روی یک host و port دلخواه اجرا کنید یا به Django بگویید که یک فایل settings مشخص را بارگذاری کند. برای مثال:
python manage.py runserver 127.0.0.1:8001 --settings=mysite.settings
وقتی با چند environment مختلف سروکار دارید که هرکدام نیاز به تنظیمات جداگانه دارند، میتوانید برای هر محیط یک فایل settings جدا ایجاد کنید.
این سرور فقط برای development طراحی شده و برای استفاده در production مناسب نیست. برای استقرار Django در محیط production، باید آن را به صورت یک WSGI application با وبسرورهایی مانند Apache، Gunicorn یا uWSGI اجرا کنید، یا به صورت یک ASGI application با وبسرورهایی مثل Daphne یا Uvicorn.
اطلاعات بیشتر دربارهی استقرار Django با وبسرورهای مختلف را میتوانید در این صفحه پیدا کنید.
در فصل ۱۷ توضیح داده شده که چگونه میتوانید یک محیط production برای پروژههای جنگو خود راهاندازی کنید.
تنظیمات پروژه در جنگو
بیایید فایل settings.py را باز کنیم و به تنظیمات پروژه نگاهی بیندازیم. Django چندین تنظیم پیشفرض در این فایل قرار داده است، اما اینها تنها بخشی از تمام تنظیمات جنگو موجود هستند. فهرست کامل تنظیمات به همراه مقادیر پیشفرضشان را میتوانید در این صفحه ببینید:
https://docs.djangoproject.com/en/5.0/ref/settings/
بیایید بعضی از تنظیمات مهم پروژه را مرور کنیم:
DEBUG: یک مقدار Boolean است که حالت debug پروژه را روشن یا خاموش میکند. اگر روی True قرار بگیرد، Django هنگام بروز خطاهای کنترلنشده خطا هارا با جزییات نمایش میدهد. در محیط production باید آن را روی False بگذارید. هرگز پروژه را با DEBUG=True در محیط production اجرا نکنید، چون دادههای حساس پروژه برای همه کاربران سایت افشا خواهند شد.
ALLOWED_HOSTS: در حالت debug یا هنگام اجرای تستها اعمال نمیشود. وقتی پروژه را به محیط production منتقل کردید و DEBUG=False شد، باید نام دامنه یا هاست خود را به این تنظیم اضافه کنید تا Django بتواند سایت به نام دامنه مشخص شده سرویس دهد.
INSTALLED_APPS: یکی از تنظیماتی است که در تمام پروژهها در حین توسعه نیاز به ویرایش دارد. این بخش به فریمورک جنگو میگوید چه برنامههایی در این سایت فعال هستند. بهطور پیشفرض شامل موارد زیر است:
django.contrib.admin: مدیریت سایت.
django.contrib.auth: فریمورک احراز هویت.
django.contrib.contenttypes: فریمورک مدیریت انواع محتوا.
django.contrib.sessions: فریمورک مدیریت سشنها.
django.contrib.messages: فریمورک پیامرسانی.
django.contrib.staticfiles: فریمورک مدیریت فایلهای استاتیک مانند CSS، JavaScript و تصاویر.
MIDDLEWARE: یک لیست است که شامل کد های واسطی است که باید اجرا شوند.
ROOT_URLCONF: ماژول Python را مشخص میکند که الگوهای root URL برنامه در آن تعریف شدهاند.
DATABASES: یک dictionary است که تنظیمات دیتابیسهای مورد استفاده در پروژه را نگه میدارد. همیشه باید یک دیتابیس پیشفرض وجود داشته باشد. پیکربندی پیشفرض از SQLite3 استفاده میکند.
LANGUAGE_CODE: زبان پیشفرض سایت Django را مشخص میکند.
USE_TZ: تعیین میکند پشتیبانی از timezone فعال باشد یا نه. Django بهطور پیشفرض از تاریخ و زمانهای وابسته به منطقه زمانی پشتیبانی میکند. این تنظیم وقتی پروژهای را با دستور startproject میسازید روی True قرار دارد.
نگران نباشید اگر الان همهی این تنظیمات برایتان روشن نیست؛ در فصلهای بعدی با هر کدام از آنها بیشتر آشنا خواهید شد.
پروژه و Applications در جنگو چیست ؟
در طول این کتاب، بارها با اصطلاحات project و application روبهرو خواهید شد.
در جنگو، یک پروژه در واقع یک نسخه نصب شده از Django همراه با تنظیمات آن است.
یک application مجموعهای از models، views، templates و URLs است. برنامهها با فریمورک تعامل میکنند تا قابلیتهای خاصی فراهم کنند و میتوانند در پروژههای مختلف هم استفاده شوند.
میتوانید یک project را مانند وبسایت خود در نظر بگیرید که شامل چندین application مثل وبلاگ، ویکی یا انجمن است؛ و هر کدام از این برنامهها میتوانند در پروژههای Django دیگر هم به کار بروند.
عکس 1.4 ساختار یک Django project را نشان میدهد.
ایجاد یک Application در جنگو
بیایید اولین Django application خود را بسازیم. ما قرار است یک blog application را از صفر پیادهسازی کنیم.
در shell prompt و از مسیر اصلی پروژه، دستور زیر را اجرا کنید:
python manage.py startapp blog
این دستور ساختار پایهی application را ایجاد میکند که به شکل زیر خواهد بود:
blog/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
فایلهای ایجادشده به این صورت هستند:
__init__.py: یک فایل خالی که به Python اعلام میکند پوشهی blog یک Python module است.
admin.py: جایی که میتوانید مدلها را ثبت کنید تا در پنل مدیریت پیشفرض جنگو نمایش داده شوند (استفاده از این قسمت اختیاری است).
apps.py: شامل تنظیمات اصلی blog application است.
migrations: این پوشه مایگریشنهای دیتابیس مربوط به برنامه را نگه میدارد. مایگریشنها تغییرات مدلها را دنبال میکنند و دیتابیس را هماهنگ میسازند. این پوشه یک فایل خالی __init__.py هم دارد.
models.py: شامل data models برنامه است. همهی Django applications باید یک فایل models.py داشته باشند، حتی اگر خالی بماند.
tests.py: جایی برای نوشتن تستهای مربوط به برنامه.
views.py: منطق اصلی برنامه در اینجا قرار میگیرد؛ هر view یک درخواست HTTP را دریافت میکند، آن را پردازش کرده و یک پاسخ برمیگرداند.
شروع ساخت Blog Data Models در جنگو
به یاد داشته باشید که یک Python object مجموعهای از داده و متدها است. Classes الگو یا طرحی برای ترکیب داده و عملکردها هستند. ایجاد یک class جدید به معنای تعریف یک نوع شیء جدید است که میتوانید نمونههایی از آن بسازید.
یک Django model منبع اطلاعات درباره رفتار دادههای شما است. این مدل در قالب یک Python class تعریف میشود که از django.db.models.Model ارثبری میکند. هر مدل به یک جدول دیتابیس نگاشت میشود و هر attribute از کلاس، نمایندهی یک database field خواهد بود.
وقتی یک مدل ایجاد میکنید، Django یک API قدرتمند در اختیار شما قرار میدهد تا بتوانید بهسادگی دادههای دیتابیس را استفاده کنید.
ما در این بخش database models مربوط به blog application را تعریف میکنیم. سپس برای مدلها database migrations ایجاد خواهیم کرد تا جداول دیتابیس مربوطه ساخته شوند. هنگام اجرای مایگریشنها، Django یک جدول برای هر مدل تعریفشده در پروژه خواهد ساخت.
models.py
ایجاد مدل Post
در اولین گام، یک Post Model تعریف میکنیم تا بتوانیم پست های بلاگ را در دیتابیس ذخیره کنیم.
کد زیر را به فایل models.py در blog application اضافه کنید. خطوط جدید به صورت bold مشخص شدهاند:
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 یک برچسب کوتاه است که فقط شامل حروف، اعداد، خط زیر (
_
) یا خط تیره (-
) میباشد. یک پست با عنوان
Django Reinhardt: A legend of Jazz
میتواند slugای مانند این داشته باشد:django-reinhardt-legend-jazz
ما از فیلد slug برای ساخت URLهای زیبا و SEO-friendly برای پستهای وبلاگ در فصل ۲ استفاده خواهیم کرد.body: این فیلد برای ذخیره بدنهی پست است. این یک فیلد TextField است که در دیتابیس SQL به یک ستون TEXT تبدیل میشود.
ما همچنین یک متد __str__به کلاس مدل اضافه کردهایم. این متد پیشفرض Python برای برگرداندن یک رشته با ظاهری قابل خواندن توسط انسان از شیء است. Django از این متد برای نمایش نام شیء در بسیاری از مکانها مانند Django administration site استفاده خواهد کرد.
بیایید نگاهی بیندازیم به اینکه چطور این مدل و فیلدهای آن به یک جدول دیتابیس و ستونها ترجمه میشوند. نمودار زیر مدل Post و جدول دیتابیسی که Django هنگام همگامسازی مدل با دیتابیس ایجاد خواهد کرد را نشان میدهد:
افزودن فیلدهای datetime
اکنون ادامه میدهیم و فیلدهای مختلف datetime را به مدل Post اضافه میکنیم. هر پست باید در یک تاریخ و زمان مشخص منتشر شود. بنابراین به فیلدی برای ذخیره تاریخ و زمان انتشار نیاز داریم. همچنین میخواهیم تاریخ و زمان ایجاد شدن شیء Post و آخرین زمان تغییر آن را ذخیره کنیم.فایل models.py در blog application را به شکل زیر ویرایش کنید؛ خطوط جدید با bold مشخص شدهاند:
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 را ایمپورت کردهایم. متد timezone.now زمان فعلی را در قالبی برمیگرداند که به timezone آگاه است. میتوانید آن را نسخهی آگاه به منطقه زمانی از متد استاندارد Python یعنی datetime.now در نظر بگیرید.
روش دیگر برای تعریف مقادیر پیشفرض برای فیلدهای مدل، استفاده از مقادیر پیشفرض محاسبهشده توسط دیتابیس است. این قابلیت از نسخه Django 5 معرفی شد و به شما اجازه میدهد از توابع داخلی دیتابیس برای تولید مقادیر پیشفرض استفاده کنید. به عنوان مثال، کد زیر تاریخ و زمان فعلی سرور دیتابیس را به عنوان مقدار پیشفرض برای فیلد publish قرار میدهد:
from django.db import modelsfrom
django.db.models.functions import Now
class Post(models.Model):
# ...
publish = models.DateTimeField(db_default=Now())
برای استفاده از مقادیر پیشفرض تولیدشده توسط دیتابیس، به جای default از ویژگی db_default استفاده میکنیم. در این مثال، ما از تابع دیتابیس Now استفاده میکنیم. این تابع هدفی مشابه default=timezone.now دارد، با این تفاوت که به جای مقدار زمان تولیدشده توسط Python، از تابع ()NOW دیتابیس برای تولید مقدار اولیه استفاده میکند.
میتوانید اطلاعات بیشتر درباره ویژگی db_default را در این صفحه بخوانید:
https://docs.djangoproject.com/en/5.0/ref/models/fields/#django.db.models.Field.db_default
فهرست تمام توابع دیتابیس موجود را نیز میتوانید در این صفحه پیدا کنید:
https://docs.djangoproject.com/en/5.0/ref/models/database-functions/
بیایید با نسخه قبلی فیلد ادامه دهیم: