FA-TOOLS — Header Component

آموزش ساخت وب‌سایت ساده با Django

سلام رفیق برنامه‌نویس! اگه دنبال یه راه سریع و کارآمد برای ساخت وب‌سایت ساده خودت هستی، بدون شک جنگو (Django) یکی از بهترین انتخاب‌هاست. این فریم‌ورک پایتونی، با فلسفه “باتری‌های همراه” (Batteries Included)، بهت کمک می‌کنه تا بدون درگیر شدن با جزئیات زیاد، تمرکزت رو روی منطق اصلی اپلیکیشن بذاری و محصولت رو سریع‌تر به دست کاربر برسونی. تو این مقاله، قراره قدم به قدم با هم یه وب‌سایت ساده رو با جنگو بسازیم، از نصب و راه‌اندازی تا ساختاردهی و نمایش اطلاعات. آماده‌ای که وب‌سایتتو با جنگوو (این اولین غلط املایی) بسازی و ایده‌هاتو عملی کنی؟ اگه تو این مسیر به ابزارها و کدهای آماده نیاز داشتی، حتماً یه سری به [ابزارهای کدنویسی ما](https://fa-tools.ir/) بزن، کلی چیز بدرد بخور اونجا پیدا می‌کنی! برای سوالات فوری هم می‌تونی با شماره [09202232789](tel:09202232789) تماس بگیری.

🛣️ نقشه راه ساخت وب‌سایت با جنگو (یک نگاه)

آموزش ساخت وب‌سایت ساده با Django — تصویر 1

1️⃣ راه‌اندازی محیط

  • ✔️ نصب پایتون و Pip
  • ✔️ ساخت محیط مجازی
  • ✔️ نصب جنگو

2️⃣ ساخت پروژه

  • ✔️ ایجاد پروژه اصلی
  • ✔️ ساخت اپلیکیشن‌ها
  • ✔️ اجرای سرور توسعه

3️⃣ هسته وب‌سایت

  • ✔️ تعریف مدل‌ها (DB)
  • ✔️ ساخت ویوها (Logic)
  • ✔️ طراحی تمپلیت‌ها (UI)

4️⃣ جذابیت و توسعه

  • ✔️ مدیریت فایل‌های استاتیک
  • ✔️ لینک‌دهی URLها
  • ✔️ عیب‌یابی و پیشرفت

این نقشه راه، بهت کمک می‌کنه همیشه بدونی کجای کار هستی و قدم بعدی چیه. بزن بریم!

چرا جنگو برای وب‌سایت ساده؟

آموزش ساخت وب‌سایت ساده با Django — تصویر 2

جنگو یه فریم‌ورک قدرتمنده که برای ساخت اپلیکیشن‌های پیچیده هم ازش استفاده میشه، اما نباید این تصور رو داشته باشیم که فقط به درد پروژه‌های بزرگ می‌خوره. اتفاقاً، برای وب‌سایت‌های ساده هم فوق‌العاده است. چرا؟
اول اینکه، جنگو با پایتون نوشته شده و اگه با پایتون آشنا باشی، یادگیریش برات مثل آب خوردنه. دوم، کلی ابزار و ماژول آماده داره که سرعت توسعه رو به شکل چشمگیری بالا می‌بره. مثلاً پنل مدیریت (Admin Panel) آماده، سیستم احراز هویت کاربر، و ORM قدرتمند که کار با دیتابیس رو خیلی راحت می‌کنه. نیازی نیست خودت چرخ رو از اول اختراع کنی.

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

پیش‌نیازها: چی لازم داری رفیق؟

آموزش ساخت وب‌سایت ساده با Django — تصویر 3

قبل از اینکه بزنیم به دل کدنویسی، مطمئن شو که ابزارهای لازم رو روی سیستمت داری. نگران نباش، چیز پیچیده‌ای نیست:

نصب پایتون و pip

پایتون، زبان برنامه‌نویسی اصلی جنگو است. اگه پایتون ۳ (ترجیحاً نسخه ۳.۸ به بالا) رو سیستم ندارید، اول از همه باید نصبش کنید. `pip` هم مدیر پکیج پایتون هست که برای نصب کتابخانه‌ها مثل خود جنگو بهش نیاز داریم. معمولاً با نصب پایتون، `pip` هم به صورت خودکار نصب میشه.

برای بررسی وجود پایتون و `pip`، تو ترمینال یا Command Prompt این دستورات رو بزن:

“`bash
python –version
pip –version
“`

اگه خروجی نشون داد که نصب شده، که دمت گرم. اگه نه، می‌تونی از سایت رسمی پایتون (python.org) دانلودش کنی و نصب رو انجام بدی.

ایجاد محیط مجازی (Virtual Environment)

این بخش خیلی مهمه! هیچ وقت جنگو یا هر پکیج پایتونی دیگه رو به صورت سراسری (Global) روی سیستمت نصب نکن. محیط مجازی بهت کمک می‌کنه که برای هر پروژه، یه فضای ایزوله و جداگانه از پکیج‌ها داشته باشی. اینجوری پکیج‌های یه پروژه با پروژه‌های دیگه قاطی نمی‌شه و مشکلات وابستگی (Dependency Hell) رو تجربه نمی‌کنی.

برای ساخت یه محیط مجازی (مثلاً با اسم `venv`):

“`bash
python -m venv venv
“`

بعد از ساخت، باید فعالش کنی.

* **لینوکس/مک:**
“`bash
source venv/bin/activate
“`
* **ویندوز (PowerShell):**
“`powershell
.venvScriptsActivate.ps1
“`
* **ویندوز (CMD):**
“`cmd
venvScriptsactivate.bat
“`

حالا می‌بینی که اسم `(venv)` کنار خط فرمان تو ظاهر میشه. این یعنی محیط مجازی فعال شده و هرچیزی رو که نصب کنی، فقط داخل این محیط خواهد بود.

نصب جنگو

بعد از فعال کردن محیط مجازی، حالا وقتشه که جنگو رو نصب کنیم. از `pip` برای این کار استفاده می‌کنیم:

“`bash
pip install django
“`

چند لحظه صبر کن تا جنگو و تمام وابستگی‌هاش نصب بشن. بعد از اتمام، می‌تونی با این دستور مطمئن بشی که نصب شده:

“`bash
django-admin –version
“`
حالا می‌بینی که نسخه جنگو رو بهت نمایش میده. عالیه، آماده‌ایم برای شروع پروژه! می‌تونی برای دیدن کدهای آماده مربوط به پایتون، به [این صفحه](https://fa-tools.ir/snippets/python/) سر بزنی.

قدم اول: ساخت پروژه جنگو

حالا که همه چی رو آماده کردیم، وقتشه که پروژه جنگو رو استارت بزنیم.

شروع پروژه جدید

پروژه جنگو در واقع کانتینر اصلی اپلیکیشن شماست که تنظیمات و کانفیگ‌های سراسری رو نگهداری می‌کنه. تو محیط مجازی فعال شده، این دستور رو بزن:

“`bash
django-admin startproject mysite .
“`

توضیح دستور:
* `django-admin`: ابزار خط فرمان جنگو.
* `startproject`: دستور برای شروع یه پروژه جدید.
* `mysite`: اسم پروژه شما. می‌تونی هر اسمی که دوست داری بذاری.
* `.`: نقطه آخر مهمه! این نقطه باعث میشه که پروژه داخل همین پوشه‌ای که الان هستی ساخته بشه، نه داخل یه پوشه `mysite` دیگه. این کار ساختار پوشه‌بندی رو تمیزتر نگه می‌داره.

بعد از اجرای این دستور، یه سری فایل و پوشه ساخته میشه:

“`
.
├── manage.py
└── mysite/
├── __init__.py
├── asgi.py
├── settings.py
├── urls.py
└── wsgi.py
“`

* `manage.py`: یه اسکریپت که باهاش می‌تونی کارهای مدیریتی پروژه مثل اجرای سرور، ساخت اپلیکیشن، کار با دیتابیس و… رو انجام بدی.
* `mysite/` (داخلی): پوشه اصلی پروژه که تنظیمات رو شامل میشه.
* `settings.py`: قلب پروژه شما! تمام تنظیمات مثل اتصال دیتابیس، اپلیکیشن‌های نصب شده، فایل‌های استاتیک و… اینجا تعریف میشه.
* `urls.py`: مسیرهای URL اصلی پروژه شما.
* `wsgi.py` و `asgi.py`: برای دیپلوی پروژه در محیط‌های Production استفاده میشن. فعلاً باهاشون کاری نداریم.

اجرای سرور توسعه

جنگو یه سرور توسعه داخلی داره که برای تست و برنامه‌نویسیی (این غلط املایی دوم) تو محیط لوکال خیلی مناسبه. برای اجراش، تو همون پوشه‌ای که فایل `manage.py` هست، این دستور رو بزن:

“`bash
python manage.py runserver
“`

اگه همه چیز درست باشه، یه پیامی مثل این رو می‌بینی:

“`
Watching for file changes with StatReloader
Performing system checks…

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run ‘python manage.py migrate’ to apply them.
September 29, 2023 – 10:00:00
Django version 4.2.5, 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/`. اگه صفحه “The install worked successfully! Congratulations!” رو دیدی، یعنی پروژه جنگو با موفقیت بالا اومده. تبریک!

یه نکته: اون پیامی که میگه `You have 18 unapplied migration(s)` رو فعلاً نادیده بگیر. بعداً باهاش کار داریم.

ساخت اولین اپلیکیشن

تو جنگو، هر بخش از وب‌سایت (مثلاً وبلاگ، گالری، بخش تماس با ما) رو به صورت یه “اپلیکیشن” جداگانه می‌سازیم. این کار باعث میشه پروژمون ماژولار و قابل نگهداری باشه. بیا یه اپلیکیشن ساده به اسم `blog` برای پست‌ها بسازیم:

“`bash
python manage.py startapp blog
“`

با این دستور، یه پوشه `blog` کنار `manage.py` و `mysite` ساخته میشه که ساختارش این شکلیه:

“`
.
├── manage.py
├── mysite/
└── blog/
├── __init__.py
├── admin.py
├── apps.py
├── migrations/
├── models.py
├── tests.py
└── views.py
“`

حالا باید جنگو رو در جریان قرار بدی که یه اپلیکیشن جدید به اسم `blog` داریم. برای این کار، فایل `mysite/settings.py` رو باز کن و `blog` رو به لیست `INSTALLED_APPS` اضافه کن:

“`python
# mysite/settings.py

INSTALLED_APPS = [
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘blog’, # اینجا اپلیکیشن جدید رو اضافه می‌کنیم
]
“`

قدم دوم: طراحی مدل‌ها (Model Design)

مدل‌ها (Models) تو جنگو، در واقع تعریف کننده ساختار داده‌های شما تو دیتابیس هستن. هر مدل، یه جدول تو دیتابیس رو نمایش میده و هر خصوصیت (Attribute) مدل، یه ستون تو اون جدول. جنگو با استفاده از ORM (Object-Relational Mapper) کار با دیتابیس رو خیلی راحت می‌کنه، یعنی نیازی نیست SQL خام بنویسی.

تعریف مدل در `models.py`

فایل `blog/models.py` رو باز کن و یه مدل ساده برای پست‌های وبلاگ تعریف کن:

“`python
# blog/models.py

from django.db import models
from django.utils import timezone

class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
pub_date = models.DateTimeField(default=timezone.now)

def __str__(self):
return self.title
“`

توضیح مدل `Post`:
* `title`: عنوان پست، از نوع `CharField` با حداکثر طول ۲۰۰ کاراکتر.
* `content`: محتوای پست، از نوع `TextField` که برای متن‌های طولانی مناسبه.
* `pub_date`: تاریخ انتشار، از نوع `DateTimeField` که به صورت پیش‌فرض زمان فعلی رو ست می‌کنه.
* متد `__str__`: این متد مشخص می‌کنه که وقتی یه شیء `Post` رو پرینت می‌کنی، چی نمایش داده بشه. اینجا عنوان پست رو برمی‌گردونه.

ساخت دیتابیس (Migrations)

حالا که مدل رو تعریف کردی، باید به جنگو بگی که این مدل رو به دیتابیس تبدیل کنه. برای این کار، دو تا مرحله داریم:

1. **ساخت Migrationها:**
“`bash
python manage.py makemigrations blog
“`
این دستور یه فایل تو پوشه `blog/migrations` می‌سازه که حاوی دستورالعمل‌های SQL برای ساخت جدول `Post` تو دیتابیسه.

2. **اعمال Migrationها:**
“`bash
python manage.py migrate
“`
این دستور تمام Migrationهای موجود (شامل Migrationهای خود جنگو برای `admin`, `auth` و…) رو به دیتابیس اعمال می‌کنه و جدول‌ها رو می‌سازه. بعد از این مرحله، اون ارور `unapplied migration(s)` که قبلاً دیدی، دیگه ظاهر نمیشه.

کار با Admin Panel

یکی از قابلیت‌های فوق‌العاده جنگو، پنل مدیریت آماده و قدرتمندشه. می‌تونی مدل `Post` رو تو این پنل ثبت کنی تا بتونی به راحتی پست‌ها رو اضافه، ویرایش و حذف کنی.

1. **ساخت کاربر مدیر (Superuser):**
“`bash
python manage.py createsuperuser
“`
با این دستور، یه نام کاربری، ایمیل و رمز عبور برای خودت انتخاب می‌کنی. این کاربر قابلیت دسترسی کامل به پنل مدیریت رو داره.

2. **ثبت مدل `Post` در Admin:**
فایل `blog/admin.py` رو باز کن و کد زیر رو بهش اضافه کن:

“`python
# blog/admin.py

from django.contrib import admin
from .models import Post

admin.site.register(Post)
“`

حالا سرور توسعه رو دوباره اجرا کن (`python manage.py runserver`) و برو به آدرس `http://127.0.0.1:8000/admin/`. با نام کاربری و رمز عبوری که ساختی وارد شو. می‌بینی که مدل `Post` حالا تو لیست اپلیکیشن `Blog` موجوده. می‌تونی روش کلیک کنی و چند تا پست جدید اضافه کنی تا تو مراحل بعدی ازشون استفاده کنیم.

🔍 تفاوت CharField و TextField

ویژگی توضیحات
CharField برای ذخیره رشته‌های متنی کوتاه و خطی (مثل عنوان، نام، ایمیل). حتماً نیاز به `max_length` دارد.
TextField برای ذخیره متن‌های طولانی و چند خطی (مثل محتوای مقاله، توضیحات). `max_length` نیاز نیست.

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

قدم سوم: ساخت ویوها و تمپلیت‌ها

حالا که داده‌هامون رو تو دیتابیس داریم، وقتشه که اون‌ها رو به کاربر نشون بدیم. اینجاست که `Views` و `Templates` وارد بازی میشن.

نوشتن منطق View در `views.py`

`View` در جنگو، یه تابع پایتون یا کلاس هست که درخواست کاربر رو دریافت می‌کنه، داده‌ها رو از مدل‌ها می‌گیره و در نهایت یه پاسخ (معمولاً یه صفحه HTML) رو برمی‌گردونه. فایل `blog/views.py` رو باز کن و یه View برای نمایش لیست پست‌ها بنویس:

“`python
# blog/views.py

from django.shortcuts import render
from .models import Post

def post_list(request):
posts = Post.objects.all().order_by(‘-pub_date’)
context = {‘posts’: posts}
return render(request, ‘blog/post_list.html’, context)
“`

توضیح کد:
* `from django.shortcuts import render`: تابع `render` برای رندر کردن تمپلیت‌های HTML استفاده میشه.
* `from .models import Post`: مدل `Post` رو ایمپورت می‌کنیم تا بتونیم باهاش کار کنیم.
* `posts = Post.objects.all().order_by(‘-pub_date’)`: اینجا با استفاده از ORM جنگو، تمام آبجکت‌های `Post` رو از دیتابیس می‌گیریم و بر اساس تاریخ انتشار (جدیدترین به قدیمی‌ترین) مرتب می‌کنیم. `-` قبل از `pub_date` به معنی مرتب‌سازی نزولی (Descending) است.
* `context = {‘posts’: posts}`: داده‌هایی که می‌خوایم به تمپلیت بفرستیم رو تو یه دیکشنری به اسم `context` قرار می‌دیم.
* `return render(request, ‘blog/post_list.html’, context)`: این خط، تمپلیت `blog/post_list.html` رو با داده‌های `context` رندر می‌کنه و به عنوان پاسخ به مرورگر برمی‌گردونه.

طراحی قالب HTML (Templates)

تمپلیت‌ها فایل‌های HTML هستن که با استفاده از “زبان تمپلیت جنگو” (Django Template Language – DTL) می‌تونن داده‌های پایتونی رو نمایش بدن.
اول، یه پوشه به اسم `templates` تو پوشه `blog` بساز، و داخل `templates` یه پوشه دیگه به اسم `blog` بساز (یعنی `blog/templates/blog/`). این ساختار برای جلوگیری از تداخل اسم تمپلیت‌ها بین اپلیکیشن‌های مختلف جنگو است.
حالا فایل `blog/templates/blog/post_list.html` رو بساز و کد زیر رو توش کپی کن:

“`html

لیست پست‌ها – وب‌سایت من

body { font-family: ‘Segoe UI’, Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; margin: 0; padding: 20px; background-color: #f4f4f4; color: #333; }
.container { max-width: 800px; margin: auto; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
h1 { color: #2c3e50; text-align: center; margin-bottom: 30px; }
.post { background-color: #e9ecef; border-left: 5px solid #007bff; padding: 15px 20px; margin-bottom: 20px; border-radius: 5px; }
.post h2 { margin-top: 0; color: #007bff; font-size: 1.8em; }
.post p { margin-bottom: 10px; font-size: 1.1em; }
.post .date { font-size: 0.9em; color: #666; text-align: left; }
@media (max-width: 600px) {
body { padding: 10px; }
.container { padding: 20px; }
h1 { font-size: 1.8em; }
.post h2 { font-size: 1.5em; }
}

آخرین پست‌ها

{% for post in posts %}

{{ post.title }}

{{ post.content|truncatechars:200 }}

تاریخ انتشار: {{ post.pub_date|date:”Y/m/d H:i” }}

{% empty %}

هیچ پستی برای نمایش وجود ندارد.

{% endfor %}

“`

توجه کن که از تگ‌های `{% for … %}` و `{{ … }}` برای نمایش داده‌های پایتونی استفاده شده. `posts` همون دیکشنری `context` هست که از `views.py` فرستادیم. `truncatechars:200` هم یه فیلتر جنگو برای خلاصه کردن متن هست.

اتصال URLها

آخرین مرحله، اتصال `View` به یه `URL` مشخصه. جنگو برای مدیریت `URL`ها از فایل‌های `urls.py` استفاده می‌کنه. ما باید دو تا فایل `urls.py` داشته باشیم: یکی برای پروژه اصلی (`mysite/urls.py`) و یکی برای اپلیکیشن `blog` (`blog/urls.py`).

1. **ساخت `blog/urls.py`:**
این فایل رو تو پوشه `blog` بساز و کد زیر رو توش قرار بده:

“`python
# blog/urls.py

from django.urls import path
from . import views

urlpatterns = [
path(”, views.post_list, name=’post_list’),
]
“`
* `path(”, views.post_list, name=’post_list’)`: این خط میگه که اگه `URL` خالی بود (یعنی ریشه اپلیکیشن `blog`)، تابع `post_list` از `views.py` اجرا بشه. `name=’post_list’` هم یه اسم برای این `URL`ه که تو تمپلیت‌ها و جاهای دیگه می‌تونیم ازش استفاده کنیم.

2. **تنظیم `mysite/urls.py` (پروژه اصلی):**
حالا باید `mysite/urls.py` رو ویرایش کنیم تا `URL`های اپلیکیشن `blog` رو شامل بشه:

“`python
# mysite/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘blog/’, include(‘blog.urls’)), # اینجا URLهای اپلیکیشن blog رو اضافه می‌کنیم
]
“`
* `path(‘blog/’, include(‘blog.urls’))`: این خط یعنی هر درخواستی که با `blog/` شروع میشه، به فایل `blog/urls.py` هدایت میشه تا بقیه مسیر رو پیدا کنه.

حالا سرور توسعه رو دوباره اجرا کن (`python manage.py runserver`) و برو به آدرس `http://127.0.0.1:8000/blog/`. اگه پست‌هایی که تو پنل مدیریت اضافه کرده بودی رو دیدی، تبریک! اولین وب‌سایت جنگو شما آماده است. برای اطلاعات بیشتر در مورد HTML و CSS می‌تونی به [این اسنیپت‌های HTML](https://fa-tools.ir/snippets/html/) و [این اسنیپت‌های CSS](https://fa-tools.ir/snippets/css/) مراجعه کنی.

قدم چهارم: اضافه کردن استایل (CSS) و اسکریپت (JS)

استایل‌ها (CSS) و اسکریپت‌ها (JS) فایل‌های استاتیک پروژه شما هستند که ظاهر و رفتار صفحات رو کنترل می‌کنند. جنگو یه سیستم برای مدیریت این فایل‌ها داره.

مدیریت فایل‌های استاتیک

1. **ساخت پوشه `static`:**
تو ریشه پروژه (کنار `manage.py` و `blog` و `mysite`) یه پوشه به اسم `static` بساز. تو این پوشه، هر اپلیکیشن می‌تونه یه پوشه به اسم خودش داشته باشه (مثلاً `static/blog/`) تا فایل‌های استاتیکش رو اونجا بذاره. بیا یه فایل CSS برای `blog` بسازیم: `static/blog/style.css`.
“`css
/* static/blog/style.css */
body {
font-family: ‘Vazirmatn’, sans-serif; /* فونت فارسی رو اینجا تنظیم کن */
direction: rtl; /* جهت متن راست به چپ */
text-align: right;
background-color: #f8f9fa;
color: #343a40;
}
.container {
border: 1px solid #ced4da;
border-radius: 5px;
padding: 25px;
background-color: #ffffff;
margin-top: 30px;
}
.post h2 {
color: #0056b3;
}
“`
برای فایل‌های JS هم همین کار رو می‌کنی: `static/blog/script.js`.

2. **تنظیمات `settings.py`:**
باید به جنگو بگی که فایل‌های استاتیک کجا هستند. تو فایل `mysite/settings.py` این تنظیمات رو اضافه کن (معمولاً پایین فایل موجودن و فقط نیاز به ویرایش داری):

“`python
# mysite/settings.py

import os # این خط رو اگه نیست اضافه کن

STATIC_URL = ‘static/’

# این خطوط رو اضافه یا ویرایش کن
STATICFILES_DIRS = [
os.path.join(BASE_DIR, ‘static’),
]
“`
* `STATIC_URL`: آدرسی که جنگو ازش برای پیدا کردن فایل‌های استاتیک تو مرورگر استفاده می‌کنه (مثلاً `http://127.0.0.1:8000/static/`).
* `STATICFILES_DIRS`: به جنگو میگه که کجا دنبال فایل‌های استاتیک بگرده. اینجا `BASE_DIR` به پوشه اصلی پروژه اشاره می‌کنه.

3. **جمع‌آوری فایل‌های استاتیک:**
در محیط `production`، باید تمام فایل‌های استاتیک رو تو یه پوشه واحد جمع‌آوری کنی. تو محیط توسعه، جنگو خودش این کار رو انجام میده، اما بهتره با این دستور آشنا باشی:
“`bash
python manage.py collectstatic
“`

لینک کردن CSS و JS

برای استفاده از فایل‌های استاتیک تو تمپلیت‌ها، باید از تگ‌های مخصوص جنگو استفاده کنی. فایل `blog/templates/blog/post_list.html` رو دوباره باز کن و قسمت “ رو ویرایش کن:

“`html

لیست پست‌ها – وب‌سایت من
{% load static %} {# این خط رو اضافه کن #}
{# این خط رو اضافه کن #}
{# اگه فایل JS داری، این رو هم اضافه کن #}

{# بقیه کد HTML #}

“`
* `{% load static %}`: این خط تو تمپلیت‌ها ضروریه تا بتونی از تگ `static` استفاده کنی.
* `{% static ‘blog/style.css’ %}`: این تگ به جنگو میگه مسیر صحیح فایل `style.css` رو پیدا کنه.

حالا اگه سرور رو اجرا کنی و صفحه رو رفرش کنی، باید استایل‌های جدید اعمال شده باشن. می‌تونی برای کدهای آماده CSS و JS به [این صفحات](https://fa-tools.ir/snippets/css/) و [این صفحات](https://fa-tools.ir/snippets/js/) مراجعه کنی.

عیب‌یابی سریع: راه‌حل مشکلات رایج

تو مسیر برنامه‌نویسیی، حتماً به مشکلاتی برمی‌خوری. نگران نباش، این طبیعیه. اینجا به چند مشکل رایج و راه‌حلشون اشاره می‌کنم:

* **مشکل: `ModuleNotFoundError: No module named ‘django’`**
* **راه‌حل:** محیط مجازی رو فعال نکردی یا جنگو رو تو محیط مجازی فعال نصب نکردی. مطمئن شو که `(venv)` تو خط فرمان هست و دستور `pip install django` رو دوباره بزن.

* **مشکل: `KeyError: ‘posts’` تو تمپلیت**
* **راه‌حل:** مطمئن شو که تو `views.py`، `context` رو به درستی به تمپلیت پاس دادی (`context = {‘posts’: posts}`) و اسم کلید (اینجا `posts`) دقیقاً با چیزی که تو تمپلیت استفاده می‌کنی مطابقت داره.

* **مشکل: صفحه سفید یا ارور `TemplateDoesNotExist`**
* **راه‌حل:**
* مطمئن شو که مسیر تمپلیت تو تابع `render` (`blog/post_list.html`) درسته.
* چک کن که پوشه `templates` و `blog` داخلش رو به درستی تو `blog/templates/blog/` ساختار دادی.
* تنظیمات `DIRS` تو `TEMPLATES` در `mysite/settings.py` رو چک کن:

“`python
# mysite/settings.py
TEMPLATES = [
{
‘BACKEND’: ‘django.template.backends.django.DjangoTemplates’,
‘DIRS’: [os.path.join(BASE_DIR, ‘templates’)], # این خط رو اضافه کن
‘APP_DIRS’: True,
# … بقیه تنظیمات
},
]
“`
همچنین مطمئن شو که `APP_DIRS: True` باشه، چون به جنگو میگه تو پوشه `templates` هر اپلیکیشن هم دنبال تمپلیت بگرده.

* **مشکل: استایل‌ها یا فایل‌های JS بارگذاری نمیشن (`404 Not Found` برای فایل‌های استاتیک)**
* **راه‌حل:**
* مطمئن شو که `{% load static %}` رو بالای تمپلیت اضافه کردی.
* مسیر فایل تو `{% static ‘blog/style.css’ %}` رو دقیقاً چک کن.
* مطمئن شو که `STATIC_URL` و `STATICFILES_DIRS` تو `mysite/settings.py` به درستی تنظیم شدن (همونطور که بالا توضیح دادم).
* پوشه `static` رو تو ریشه پروژه درست ساختی؟

* **مشکل: ارور `unapplied migration(s)` هنوز هست**
* **راه‌حل:** دستور `python manage.py migrate` رو بعد از ساخت مدل‌ها و `makemigrations` اجرا کردی؟ مطمئن شو که این دستور رو زدی.

* **مشکل: پنل مدیریت کار نمی‌کنه یا نمی‌تونی وارد بشی**
* **راه‌حل:** مطمئن شو که `createsuperuser` رو درست اجرا کردی و اطلاعات ورود رو به یاد داری. اگه فراموش کردی، می‌تونی دوباره `createsuperuser` رو اجرا کنی و یه کاربر جدید بسازی.

گام‌های بعدی: چطور پروژه رو حرفه‌ای‌تر کنی؟

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

* **جزئیات بیشتر برای پست‌ها:** یه `View` و `Template` دیگه برای نمایش جزئیات هر پست به صورت جداگانه بساز (مثلاً `blog//`).
* **فرم‌ها (Forms):** اضافه کردن فرم برای کامنت‌ها یا تماس با ما. جنگو یه سیستم فرم قوی داره.
* **احراز هویت کاربر:** به کاربران اجازه بده ثبت نام کنن، وارد بشن و خارج بشن. جنگو سیستم `auth` قوی‌ای داره.
* **استفاده از CSS Frameworks:** برای زیباتر کردن ظاهر سایت، می‌تونی از فریم‌ورک‌هایی مثل Bootstrap یا Tailwind CSS استفاده کنی. برای یادگیری وردپرس و ساخت قالب‌های حرفه‌ای هم، [این صفحه](https://fa-tools.ir/snippets/wordpress/) رو ببین.
* **دیپلوی (Deploy):** وقتی پروژه آماده شد، می‌تونی اونو روی سرورهای واقعی (مثل Heroku, DigitalOcean, Vercel, PythonAnywhere) دیپلوی کنی تا بقیه هم بتونن ببیننش.
* **تست‌نویسی:** برای اطمینان از صحت عملکرد کدها، براشون تست بنویس.

خلاصه

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

جنگو فقط یه فریم‌ورک نیست، یه جامعه بزرگ و منابع آموزشی بی‌نظیر هم داره که هرجا به مشکل خوردی، می‌تونی ازشون کمک بگیری. پس همین الان شروع کن، ایده‌هاتو پیاده‌سازی کن و از برنامه‌نویسیی (این غلط املایی سوم) لذت ببر. فراموش نکن، هرچه بیشتر کد بزنی، حرفه‌ای‌تر میشی. موفق باشی! اگر کدهای آماده و اسنیپت‌های مختلفی تو زمینه‌های گوناگون نیاز داری، به [بخش اسنیپت‌های ما](https://fa-tools.ir/snippets/) سر بزن.
“`
“`output

آموزش ساخت وب‌سایت ساده با Django

سلام رفیق برنامه‌نویس! اگه دنبال یه راه سریع و کارآمد برای ساخت وب‌سایت ساده خودت هستی، بدون شک جنگو (Django) یکی از بهترین انتخاب‌هاست. این فریم‌ورک پایتونی، با فلسفه “باتری‌های همراه” (Batteries Included)، بهت کمک می‌کنه تا بدون درگیر شدن با جزئیات زیاد، تمرکزت رو روی منطق اصلی اپلیکیشن بذاری و محصولت رو سریع‌تر به دست کاربر برسونی. تو این مقاله، قراره قدم به قدم با هم یه وب‌سایت ساده رو با جنگو بسازیم، از نصب و راه‌اندازیی تا ساختاردهی و نمایش اطلاعات. آماده‌ای که وب‌سایتتو با جنگوو بسازی و ایده‌هاتو عملی کنی؟ اگه تو این مسیر به ابزارها و کدهای آماده نیاز داشتی، حتماً یه سری به ابزارهای کدنویسی ما بزن، کلی چیز بدرد بخور اونجا پیدا می‌کنی! برای سوالات فوری هم می‌تونی با شماره 09202232789 تماس بگیری.

🛣️ نقشه راه ساخت وب‌سایت با جنگو (یک نگاه)

1️⃣ راه‌اندازی محیط

  • ✔️ نصب پایتون و Pip
  • ✔️ ساخت محیط مجازی
  • ✔️ نصب جنگو

2️⃣ ساخت پروژه

  • ✔️ ایجاد پروژه اصلی
  • ✔️ ساخت اپلیکیشن‌ها
  • ✔️ اجرای سرور توسعه

3️⃣ هسته وب‌سایت

  • ✔️ تعریف مدل‌ها (DB)
  • ✔️ ساخت ویوها (Logic)
  • ✔️ طراحی تمپلیت‌ها (UI)

4️⃣ جذابیت و توسعه

  • ✔️ مدیریت فایل‌های استاتیک
  • ✔️ لینک‌دهی URLها
  • ✔️ عیب‌یابی و پیشرفت

این نقشه راه، بهت کمک می‌کنه همیشه بدونی کجای کار هستی و قدم بعدی چیه. بزن بریم!

چرا جنگو برای وب‌سایت ساده؟

جنگو یه فریم‌ورک قدرتمنده که برای ساخت اپلیکیشن‌های پیچیده هم ازش استفاده میشه، اما نباید این تصور رو داشته باشیم که فقط به درد پروژه‌های بزرگ می‌خوره. اتفاقاً، برای وب‌سایت‌های ساده هم فوق‌العاده است. چرا؟
اول اینکه، جنگو با پایتون نوشته شده و اگه با پایتون آشنا باشی، یادگیریش برات مثل آب خوردنه. دوم، کلی ابزار و ماژول آماده داره که سرعت توسعه رو به شکل چشمگیری بالا می‌بره. مثلاً پنل مدیریت (Admin Panel) آماده، سیستم احراز هویت کاربر، و ORM قدرتمند که کار با دیتابیس رو خیلی راحت می‌کنه. نیازی نیست خودت چرخ رو از اول اختراع کنی.

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

پیش‌نیازها: چی لازم داری رفیق؟

قبل از اینکه بزنیم به دل کدنویسی، مطمئن شو که ابزارهای لازم رو روی سیستمت داری. نگران نباش، چیز پیچیده‌ای نیست:

نصب پایتون و pip

پایتون، زبان برنامه‌نویسی اصلی جنگو است. اگه پایتون ۳ (ترجیحاً نسخه ۳.۸ به بالا) رو سیستم ندارید، اول از همه باید نصبش کنید. pip هم مدیر پیکج پایتون هست که برای نصب کتابخانه‌ها مثل خود جنگو بهش نیاز داریم. معمولاً با نصب پایتون، pip هم به صورت خودکار نصب میشه.

برای بررسی وجود پایتون و pip، تو ترمینال یا Command Prompt این دستورات رو بزن:


python --version
pip --version

اگه خروجی نشون داد که نصب شده، که دمت گرم. اگه نه، می‌تونی از سایت رسمی پایتون (python.org) دانلودش کنی و نصب رو انجام بدی.

ایجاد محیط مجازی (Virtual Environment)

این بخش خیلی مهمه! هیچ وقت جنگو یا هر پکیج پایتونی دیگه رو به صورت سراسری (Global) روی سیستمت نصب نکن. محیط مجازی بهت کمک می‌کنه که برای هر پروژه، یه فضای ایزوله و جداگانه از پکیج‌ها داشته باشی. اینجوری پکیج‌های یه پروژه با پروژه‌های دیگه قاطی نمی‌شه و مشکلات وابستگی (Dependency Hell) رو تجربه نمی‌کنی.

برای ساخت یه محیط مجازی (مثلاً با اسم venv):


python -m venv venv

بعد از ساخت، باید فعالش کنی.

  • لینوکس/مک:
    
    source venv/bin/activate
    
  • ویندوز (PowerShell):
    
    .venvScriptsActivate.ps1
    
  • ویندوز (CMD):
    
    venvScriptsactivate.bat
    

حالا می‌بینی که اسم (venv) کنار خط فرمان تو ظاهر میشه. این یعنی محیط مجازی فعال شده و هرچیزی رو که نصب کنی، فقط داخل این محیط خواهد بود.

نصب جنگو

بعد از فعال کردن محیط مجازی، حالا وقتشه که جنگو رو نصب کنیم. از pip برای این کار استفاده می‌کنیم:


pip install django

چند لحظه صبر کن تا جنگو و تمام وابستگی‌هاش نصب بشن. بعد از اتمام، می‌تونی با این دستور مطمئن بشی که نصب شده:


django-admin --version

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

قدم اول: ساخت پروژه جنگو

حالا که همه چی رو آماده کردیم، وقتشه که پروژه جنگو رو استارت بزنیم.

شروع پروژه جدید

پروژه جنگو در واقع کانتینر اصلی اپلیکیشن شماست که تنظیمات و کانفیگ‌های سراسری رو نگهداری می‌کنه. تو محیط مجازی فعال شده، این دستور رو بزن:


django-admin startproject mysite .

توضیح دستور:

  • django-admin: ابزار خط فرمان جنگو.
  • startproject: دستور برای شروع یه پروژه جدید.
  • mysite: اسم پروژه شما. می‌تونی هر اسمی که دوست داری بذاری.
  • .: نقطه آخر مهمه! این نقطه باعث میشه که پروژه داخل همین پوشه‌ای که الان هستی ساخته بشه، نه داخل یه پوشه mysite دیگه. این کار ساختار پوشه‌بندی رو تمیزتر نگه می‌داره.

بعد از اجرای این دستور، یه سری فایل و پوشه ساخته میشه:


.
├── manage.py
└── mysite/
    ├── __init__.py
    ├── asgi.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py
  • manage.py: یه اسکریپت که باهاش می‌تونی کارهای مدیریتی پروژه مثل اجرای سرور، ساخت اپلیکیشن، کار با دیتابیس و… رو انجام بدی.
  • mysite/ (داخلی): پوشه اصلی پروژه که تنظیمات رو شامل میشه.
    • settings.py: قلب پروژه شما! تمام تنظیمات مثل اتصال دیتابیس، اپلیکیشن‌های نصب شده، فایل‌های استاتیک و… اینجا تعریف میشه.
    • urls.py: مسیرهای URL اصلی پروژه شما.
    • wsgi.py و asgi.py: برای دیپلوی پروژه در محیط‌های Production استفاده میشن. فعلاً باهاشون کاری نداریم.

اجرای سرور توسعه

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


python manage.py runserver

اگه همه چیز درست باشه، یه پیامی مثل این رو می‌بینی:


Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
September 29, 2023 - 10:00:00
Django version 4.2.5, 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/. اگه صفحه “The install worked successfully! Congratulations!” رو دیدی، یعنی پروژه جنگو با موفقیت بالا اومده. تبریک!

یه نکته: اون پیامی که میگه You have 18 unapplied migration(s) رو فعلاً نادیده بگیر. بعداً باهاش کار داریم.

ساخت اولین اپلیکیشن

تو جنگو، هر بخش از وب‌سایت (مثلاً وبلاگ، گالری، بخش تماس با ما) رو به صورت یه “اپلیکیشن” جداگانه می‌سازیم. این کار باعث میشه پروژمون ماژولار و قابل نگهداری باشه. بیا یه اپلیکیشن ساده به اسم blog برای پست‌ها بسازیم:


python manage.py startapp blog

با این دستور، یه پوشه blog کنار manage.py و mysite ساخته میشه که ساختارش این شکلیه:


.
├── manage.py
├── mysite/
└── blog/
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations/
    ├── models.py
    ├── tests.py
    └── views.py

حالا باید جنگو رو در جریان قرار بدی که یه اپلیکیشن جدید به اسم blog داریم. برای این کار، فایل mysite/settings.py رو باز کن و blog رو به لیست INSTALLED_APPS اضافه کن:


# mysite/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',  # اینجا اپلیکیشن جدید رو اضافه می‌کنیم
]

قدم دوم: طراحی مدل‌ها (Model Design)

مدل‌ها (Models) تو جنگو، در واقع تعریف کننده ساختار داده‌های شما تو دیتابیس هستن. هر مدل، یه جدول تو دیتابیس رو نمایش میده و هر خصوصیت (Attribute) مدل، یه ستون تو اون جدول. جنگو با استفاده از ORM (Object-Relational Mapper) کار با دیتابیس رو خیلی راحت می‌کنه، یعنی نیازی نیست SQL خام بنویسی.

تعریف مدل در models.py

فایل blog/models.py رو باز کن و یه مدل ساده برای پست‌های وبلاگ تعریف کن:


# blog/models.py

from django.db import models
from django.utils import timezone

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    pub_date = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return self.title

توضیح مدل Post:

  • title: عنوان پست، از نوع CharField با حداکثر طول ۲۰۰ کاراکتر.
  • content: محتوای پست، از نوع TextField که برای متن‌های طولانی مناسبه.
  • pub_date: تاریخ انتشار، از نوع DateTimeField که به صورت پیش‌فرض زمان فعلی رو ست می‌کنه.
  • متد __str__: این متد مشخص می‌کنه که وقتی یه شیء Post رو پرینت می‌کنی، چی نمایش داده بشه. اینجا عنوان پست رو برمی‌گردونه.

ساخت دیتابیس (Migrations)

حالا که مدل رو تعریف کردی، باید به جنگو بگی که این مدل رو به دیتابیس تبدیل کنه. برای این کار، دو تا مرحله داریم:

  1. ساخت Migrationها:
    
    python manage.py makemigrations blog
    

    این دستور یه فایل تو پوشه blog/migrations می‌سازه که حاوی دستورالعمل‌های SQL برای ساخت جدول Post تو دیتابیسه.

  2. اعمال Migrationها:
    
    python manage.py migrate
    

    این دستور تمام Migrationهای موجود (شامل Migrationهای خود جنگو برای admin, auth و…) رو به دیتابیس اعمال می‌کنه و جدول‌ها رو می‌سازه. بعد از این مرحله، اون ارور unapplied migration(s) که قبلاً دیدی، دیگه ظاهر نمیشه.

کار با Admin Panel

یکی از قابلیت‌های فوق‌العاده جنگو، پنل مدیریت آماده و قدرتمندشه. می‌تونی مدل Post رو تو این پنل ثبت کنی تا بتونی به راحتی پست‌ها رو اضافه، ویرایش و حذف کنی.

  1. ساخت کاربر مدیر (Superuser):
    
    python manage.py createsuperuser
    

    با این دستور، یه نام کاربری، ایمیل و رمز عبور برای خودت انتخاب می‌کنی. این کاربر قابلیت دسترسی کامل به پنل مدیریت رو داره.

  2. ثبت مدل Post در Admin:
    فایل blog/admin.py رو باز کن و کد زیر رو بهش اضافه کن:

    
    # blog/admin.py
    
    from django.contrib import admin
    from .models import Post
    
    admin.site.register(Post)
    

حالا سرور توسعه رو دوباره اجرا کن (python manage.py runserver) و برو به آدرس http://127.0.0.1:8000/admin/. با نام کاربری و رمز عبوری که ساختی وارد شو. می‌بینی که مدل Post حالا تو لیست اپلیکیشن Blog موجوده. می‌تونی روش کلیک کنی و چند تا پست جدید اضافه کنی تا تو مراحل بعدی ازشون استفاده کنیم.

🔍 تفاوت CharField و TextField

ویژگی توضیحات
CharField برای ذخیره رشته‌های متنی کوتاه و خطی (مثل عنوان، نام، ایمیل). حتماً نیاز به max_length دارد.
TextField برای ذخیره متن‌های طولانی و چند خطی (مثل محتوای مقاله، توضیحات). max_length نیاز نیست.

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

قدم سوم: ساخت ویوها و تمپلیت‌ها

حالا که داده‌هامون رو تو دیتابیس داریم، وقتشه که اون‌ها رو به کاربر نشون بدیم. اینجاست که Views و Templates وارد بازی میشن.

نوشتن منطق View در views.py

View در جنگو، یه تابع پایتون یا کلاس هست که درخواست کاربر رو دریافت می‌کنه، داده‌ها رو از مدل‌ها می‌گیره و در نهایت یه پاسخ (معمولاً یه صفحه HTML) رو برمی‌گردونه. فایل blog/views.py رو باز کن و یه View برای نمایش لیست پست‌ها بنویس:


# blog/views.py

from django.shortcuts import render
from .models import Post

def post_list(request):
    posts = Post.objects.all().order_by('-pub_date')
    context = {'posts': posts}
    return render(request, 'blog/post_list.html', context)

توضیح کد:

  • from django.shortcuts import render: تابع render برای رندر کردن تمپلیت‌های HTML استفاده میشه.
  • from .models import Post: مدل Post رو ایمپورت می‌کنیم تا بتونیم باهاش کار کنیم.
  • posts = Post.objects.all().order_by('-pub_date'): اینجا با استفاده از ORM جنگو، تمام آبجکت‌های Post رو از دیتابیس می‌گیریم و بر اساس تاریخ انتشار (جدیدترین به قدیمی‌ترین) مرتب می‌کنیم. - قبل از pub_date به معنی مرتب‌سازی نزولی (Descending) است.
  • context = {'posts': posts}: داده‌هایی که می‌خوایم به تمپلیت بفرستیم رو تو یه دیکشنری به اسم context قرار می‌دیم.
  • return render(request, 'blog/post_list.html', context): این خط، تمپلیت blog/post_list.html رو با داده‌های context رندر می‌کنه و به عنوان پاسخ به مرورگر برمی‌گردونه.

طراحی قالب HTML (Templates)

تمپلیت‌ها فایل‌های HTML هستن که با استفاده از “زبان تمپلیت جنگو” (Django Template Language – DTL) می‌تونن داده‌های پایتونی رو نمایش بدن.
اول، یه پوشه به اسم templates تو پوشه blog بساز، و داخل templates یه پوشه دیگه به اسم blog بساز (یعنی blog/templates/blog/). این ساختار برای جلوگیری از تداخل اسم تمپلیت‌ها بین اپلیکیشن‌های مختلف جنگو است.
حالا فایل blog/templates/blog/post_list.html رو بساز و کد زیر رو توش کپی کن:


<!-- blog/templates/blog/post_list.html -->
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>لیست پست‌ها - وب‌سایت من</title>
    <style>
        body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; margin: 0; padding: 20px; background-color: #f4f4f4; color: #333; }
        .container { max-width: 800px; margin: auto; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        h1 { color: #2c3e50; text-align: center; margin-bottom: 30px; }
        .post { background-color: #e9ecef; border-left: 5px solid #007bff; padding: 15px 20px; margin-bottom: 20px; border-radius: 5px; }
        .post h2 { margin-top: 0; color: #007bff; font-size: 1.8em; }
        .post p { margin-bottom: 10px; font-size: 1.1em; }
        .post .date { font-size: 0.9em; color: #666; text-align: right; }
        @media (max-width: 600px) {
            body { padding: 10px; }
            .container { padding: 20px; }
            h1 { font-size: 1.8em; }
            .post h2 { font-size: 1.5em; }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>آخرین پست‌ها</h1>
        {% for post in posts %}
            <div class="post">
                <h2>{{ post.title }}</h2>
                <p>{{ post.content|truncatechars:200 }}</p>
                <p class="date">تاریخ انتشار: {{ post.pub_date|date:"Y/m/d H:i" }}</p>
            </div>
        {% empty %}
            <p>هیچ پستی برای نمایش وجود ندارد.</p>
        {% endfor %}
    </div>
</body>
</html>

توجه کن که از تگ‌های {% for ... %} و {{ ... }} برای نمایش داده‌های پایتونی استفاده شده. posts همون دیکشنری context هست که از views.py فرستادیم. truncatechars:200 هم یه فیلتر جنگو برای خلاصه کردن متن هست.

اتصال URLها

آخرین مرحله، اتصال View به یه URL مشخصه. جنگو برای مدیریت URLها از فایل‌های urls.py استفاده می‌کنه. ما باید دو تا فایل urls.py داشته باشیم: یکی برای پروژه اصلی (mysite/urls.py) و یکی برای اپلیکیشن blog (blog/urls.py).

  1. ساخت blog/urls.py:
    این فایل رو تو پوشه blog بساز و کد زیر رو توش قرار بده:

    
    # blog/urls.py
    
    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('', views.post_list, name='post_list'),
    ]
    
    • path('', views.post_list, name='post_list'): این خط میگه که اگه URL خالی بود (یعنی ریشه اپلیکیشن blog)، تابع post_list از views.py اجرا بشه. name='post_list' هم یه اسم برای این URLه که تو تمپلیت‌ها و جاهای دیگه می‌تونیم ازش استفاده کنیم.
  2. تنظیم mysite/urls.py (پروژه اصلی):
    حالا باید mysite/urls.py رو ویرایش کنیم تا URLهای اپلیکیشن blog رو شامل بشه:

    
    # mysite/urls.py
    
    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('blog/', include('blog.urls')), # اینجا URLهای اپلیکیشن blog رو اضافه می‌کنیم
    ]
    
    • path('blog/', include('blog.urls')): این خط یعنی هر درخواستی که با blog/ شروع میشه، به فایل blog/urls.py هدایت میشه تا بقیه مسیر رو پیدا کنه.

حالا سرور توسعه رو دوباره اجرا کن (python manage.py runserver) و برو به آدرس http://127.0.0.1:8000/blog/. اگه پست‌هایی که تو پنل مدیریت اضافه کرده بودی رو دیدی، تبریک! اولین وب‌سایت جنگو شما آماده است. برای اطلاعات بیشتر در مورد HTML و CSS می‌تونی به این اسنیپت‌های HTML و این اسنیپت‌های CSS مراجعه کنی.

قدم چهارم: اضافه کردن استایل (CSS) و اسکریپت (JS)

استایل‌ها (CSS) و اسکریپت‌ها (JS) فایل‌های استاتیک پروژه شما هستند که ظاهر و رفتار صفحات رو کنترل می‌کنند. جنگو یه سیستم برای مدیریت این فایل‌ها داره.

مدیریت فایل‌های استاتیک

  1. ساخت پوشه static:
    تو ریشه پروژه (کنار manage.py و blog و mysite) یه پوشه به اسم static بساز. تو این پوشه، هر اپلیکیشن می‌تونه یه پوشه به اسم خودش داشته باشه (مثلاً static/blog/) تا فایل‌های استاتیکش رو اونجا بذاره. بیا یه فایل CSS برای blog بسازیم: static/blog/style.css.

    
    /* static/blog/style.css */
    body {
        font-family: 'Vazirmatn', sans-serif; /* فونت فارسی رو اینجا تنظیم کن */
        direction: rtl; /* جهت متن راست به چپ */
        text-align: right;
        background-color: #f8f9fa;
        color: #343a40;
    }
    .container {
        border: 1px solid #ced4da;
        border-radius: 5px;
        padding: 25px;
        background-color: #ffffff;
        margin-top: 30px;
    }
    .post h2 {
        color: #0056b3;
    }
    

    برای فایل‌های JS هم همین کار رو می‌کنی: static/blog/script.js.

  2. تنظیمات settings.py:
    باید به جنگو بگی که فایل‌های استاتیک کجا هستند. تو فایل mysite/settings.py این تنظیمات رو اضافه کن (معمولاً پایین فایل موجودن و فقط نیاز به ویرایش داری):

    
    # mysite/settings.py
    
    import os # این خط رو اگه نیست اضافه کن
    
    STATIC_URL = 'static/'
    
    # این خطوط رو اضافه یا ویرایش کن
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, 'static'),
    ]
    
    • STATIC_URL: آدرسی که جنگو ازش برای پیدا کردن فایل‌های استاتیک تو مرورگر استفاده می‌کنه (مثلاً http://127.0.0.1:8000/static/).
    • STATICFILES_DIRS: به جنگو میگه که کجا دنبال فایل‌های استاتیک بگرده. اینجا BASE_DIR به پوشه اصلی پروژه اشاره می‌کنه.
  3. جمع‌آوری فایل‌های استاتیک:
    در محیط production، باید تمام فایل‌های استاتیک رو تو یه پوشه واحد جمع‌آوری کنی. تو محیط توسعه، جنگو خودش این کار رو انجام میده، اما بهتره با این دستور آشنا باشی:

    
    python manage.py collectstatic
    

لینک کردن CSS و JS

برای استفاده از فایل‌های استاتیک تو تمپلیت‌ها، باید از تگ‌های مخصوص جنگو استفاده کنی. فایل blog/templates/blog/post_list.html رو دوباره باز کن و قسمت <head> رو ویرایش کن:


<!-- blog/templates/blog/post_list.html -->
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>لیست پست‌ها - وب‌سایت من</title>
    {% load static %} {# این خط رو اضافه کن #}
    <link rel="stylesheet" href="{% static 'blog/style.css' %}"> {# این خط رو اضافه کن #}
    <script src="{% static 'blog/script.js' %}"></script> {# اگه فایل JS داری، این رو هم اضافه کن #}
</head>
<body>
    {# بقیه کد HTML #}
</body>
</html>
  • {% load static %}: این خط تو تمپلیت‌ها ضروریه تا بتونی از تگ static استفاده کنی.
  • {% static 'blog/style.css' %}: این تگ به جنگو میگه مسیر صحیح فایل style.css رو پیدا کنه.

حالا اگه سرور رو اجرا کنی و صفحه رو رفرش کنی، باید استایل‌های جدید اعمال شده باشن. می‌تونی برای کدهای آماده CSS و JS به این صفحات و این صفحات مراجعه کنی.

عیب‌یابی سریع: راه‌حل مشکلات رایج

تو مسیر برنامه‌نویسیی، حتماً به مشکلاتی برمی‌خوری. نگران نباش، این طبیعیه. اینجا به چند مشکل رایج و راه‌حلشون اشاره می‌کنم:

  • مشکل: ModuleNotFoundError: No module named 'django'
    • راه‌حل: محیط مجازی رو فعال نکردی یا جنگو رو تو محیط مجازی فعال نصب نکردی. مطمئن شو که (venv) تو خط فرمان هست و دستور pip install django رو دوباره بزن.
  • مشکل: KeyError: 'posts' تو تمپلیت
    • راه‌حل: مطمئن شو که تو views.py، context رو به درستی به تمپلیت پاس دادی (context = {'posts': posts}) و اسم کلید (اینجا posts) دقیقاً با چیزی که تو تمپلیت استفاده می‌کنی مطابقت داره.
  • مشکل: صفحه سفید یا ارور TemplateDoesNotExist
    • راه‌حل:
      • مطمئن شو که مسیر تمپلیت تو تابع render (blog/post_list.html) درسته.
      • چک کن که پوشه templates و blog داخلش رو به درستی تو blog/templates/blog/ ساختار دادی.
      • تنظیمات DIRS تو TEMPLATES در mysite/settings.py رو چک کن:
        
        # mysite/settings.py
        TEMPLATES = [
            {
                'BACKEND': 'django.template.backends.django.DjangoTemplates',
                'DIRS': [os.path.join(BASE_DIR, 'templates')], # این خط رو اضافه کن
                'APP_DIRS': True,
                # ... بقیه تنظیمات
            },
        ]
        

        همچنین مطمئن شو که APP_DIRS: True باشه، چون به جنگو میگه تو پوشه templates هر اپلیکیشن هم دنبال تمپلیت بگرده.

  • مشکل: استایل‌ها یا فایل‌های JS بارگذاری نمیشن (404 Not Found برای فایل‌های استاتیک)
    • راه‌حل:
      • مطمئن شو که {% load static %} رو بالای تمپلیت اضافه کردی.
      • مسیر فایل تو {% static 'blog/style.css' %} رو دقیقاً چک کن.
      • مطمئن شو که STATIC_URL و STATICFILES_DIRS تو mysite/settings.py به درستی تنظیم شدن (همونطور که بالا توضیح دادم).
      • پوشه static رو تو ریشه پروژه درست ساختی؟
  • مشکل: ارور unapplied migration(s) هنوز هست
    • راه‌حل: دستور python manage.py migrate رو بعد از ساخت مدل‌ها و makemigrations اجرا کردی؟ مطمئن شو که این دستور رو زدی.
  • مشکل: پنل مدیریت کار نمی‌کنه یا نمی‌تونی وارد بشی
    • راه‌حل: مطمئن شو که createsuperuser رو درست اجرا کردی و اطلاعات ورود رو به یاد داری. اگه فراموش کردی، می‌تونی دوباره createsuperuser رو اجرا کنی و یه کاربر جدید بسازی.

گام‌های بعدی: چطور پروژه رو حرفه‌ای‌تر کنی؟

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

  • جزئیات بیشتر برای پست‌ها: یه View و Template دیگه برای نمایش جزئیات هر پست به صورت جداگانه بساز (مثلاً blog/<slug>/).
  • فرم‌ها (Forms): اضافه کردن فرم برای کامنت‌ها یا تماس با ما. جنگو یه سیستم فرم قوی داره.
  • احراز هویت کاربر: به کاربران اجازه بده ثبت نام کنن، وارد بشن و خارج بشن. جنگو سیستم auth قوی‌ای داره.
  • استفاده از CSS Frameworks: برای زیباتر کردن ظاهر سایت، می‌تونی از فریم‌ورک‌هایی مثل Bootstrap یا Tailwind CSS استفاده کنی. برای یادگیری وردپرس و ساخت قالب‌های حرفه‌ای هم، این صفحه رو ببین.
  • دیپلوی (Deploy): وقتی پروژه آماده شد، می‌تونی اونو روی سرورهای واقعی (مثل Heroku, DigitalOcean, Vercel, PythonAnywhere) دیپلوی کنی تا بقیه هم بتونن ببیننش.
  • تست‌نویسی: برای اطمینان از صحت عملکرد کدها، براشون تست بنویس.

خلاصه

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

جنگو فقط یه فریم‌ورک نیست، یه جامعه بزرگ و منابع آموزشی بی‌نظیر هم داره که هرجا به مشکل خوردی، می‌تونی ازشون کمک بگیری. پس همین الان شروع کن، ایده‌هاتو پیاده‌سازی کن و از برنامه‌نویسیی لذت ببر. فراموش نکن، هرچه بیشتر کد بزنی، حرفه‌ای‌تر میشی. موفق باشی! اگر کدهای آماده و اسنیپت‌های مختلفی تو زمینه‌های گوناگون نیاز داری، به بخش اسنیپت‌های ما سر بزن.
“`

Table of Contents

آخرین نوشته‌ها