<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های رضا رضایی</title>
        <link>https://virgool.io/feed/@rezarezaeedev</link>
        <description>برنامه‌نویس بک‌اند با تمرکز بر پایتون و فریم‌ورک جنگو. علاقه‌مند به ساخت برنامه‌های تحت وب مقیاس‌پذیر و قابل اعتماد. مشتاق مشارکت در پروژه‌های واقعی و پیشرفت در توسعه بک‌اند.</description>
        <language>fa</language>
        <pubDate>2026-07-06 03:48:19</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/1834221/avatar/Yl8coq.jpg?height=120&amp;width=120</url>
            <title>رضا رضایی</title>
            <link>https://virgool.io/@rezarezaeedev</link>
        </image>

                    <item>
                <title>۱.۱۵: یادگیری چرخه عمر Request/Response در جنگو | ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/%DB%B1%DB%B1%DB%B4-%DB%8C%D8%A7%D8%AF%DA%AF%DB%8C%D8%B1%DB%8C-%DA%86%D8%B1%D8%AE%D9%87-%D8%B9%D9%85%D8%B1-requestresponse-%D8%AF%D8%B1-%D8%AC%D9%86%DA%AF%D9%88-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-django-5-by-example-mvbso8xd9zfc</link>
                <description>اپیزود آخر فصل اول ترجمه کتاب جنگو ۵ با مثال - یادگیری چرخه عمر درخواست/پاسخاکنون بیایید چرخه درخواست/پاسخ (Request/Response Cycle) در جنگو را با استفاده از برنامه‌ای که ساخته‌ایم مرور کنیم.نمودار زیر یک نمونه ساده‌شده از نحوه پردازش درخواست‌های HTTP و تولید پاسخ‌های HTTP در جنگو را نشان می‌دهد.چرخه عمر رکوئست و رسپانس در جنگوبیایید فرایند Request/Response در جنگو را مرور کنیم:مرورگر وب صفحه‌ای را از طریق URL درخواست می‌کند؛ برای مثال:https://domain.com/blog/33/وب‌سرور این درخواست HTTP را دریافت کرده و آن را به جنگو ارسال می‌کند.جنگو تمام الگوهای URL تعریف‌شده در تنظیمات URL را به‌ترتیب بررسی می‌کند.فریم‌ورک هر الگو را با مسیر URL درخواست‌شده مقایسه می‌کند و به محض یافتن اولین الگویی که با URL مطابقت داشته باشد، بررسی را متوقف می‌کند.در این مثال، الگوی:/blog/&lt;id&gt;/با مسیر:/blog/33/مطابقت پیدا می‌کند.سپس جنگو View مربوط به URL منطبق را بارگذاری و اجرا می‌کند.هنگام اجرای View، یک نمونه از کلاس HttpRequest به همراه آرگومان‌های موقعیتی یا کلیدواژه‌ای (مانند id=33) به آن ارسال می‌شود.View برای بازیابی اطلاعات از پایگاه داده از Modelها استفاده می‌کند.با استفاده از ORM جنگو، اشیای QuerySet به دستورات SQL تبدیل شده و در پایگاه داده اجرا می‌شوند.View با استفاده از تابع render() یک Template را رندر می‌کند و شیء Post را به‌عنوان یک متغیر Context به Template ارسال می‌کند.در نهایت، محتوای رندرشده توسط View در قالب یک شیء HttpResponse بازگردانده می‌شود.به‌طور پیش‌فرض، نوع محتوای (Content-Type) این پاسخ برابر با text/html است.شما می‌توانید همیشه این نمودار را به‌عنوان مرجع پایه برای درک نحوه پردازش درخواست‌ها در جنگو در نظر بگیرید.برای ساده‌تر شدن توضیح، این نمودار Middlewareهای جنگو را نشان نمی‌دهد.در مثال‌های مختلف این کتاب از Middleware استفاده خواهید کرد و در فصل ۱۷ با عنوان Going Live (به معنای پروژه واقعی در محیط اینترنت) نیز نحوه ایجاد Middleware سفارشی (Custom Middleware) را خواهید آموخت.نکته مترجم: به زبان خیلی ساده، یک رکوئست از زمانی که توسط مرورگر ارسال میشود و توسط پایتون و جنگو تحلیل میشود تا زمانی که رسپانس آن به مرورگر کاربر بازمیگردد را لایف سایکل یا چرخه عمر جنگو میگویند.خلاصه دستورات استفاده شده در این فصلدر این فصل با مجموعه‌ای از دستورات مدیریتی جنگو (Django Management Commands) آشنا شدید. لازم است این دستورات را به‌خوبی یاد بگیرید، زیرا در سراسر کتاب بارها از آن‌ها استفاده خواهد شد.در ادامه، دستورات معرفی‌شده در این فصل را مرور می‌کنیم.ایجاد یک پروژه جدید جنگو با نام mysiteبرای ایجاد ساختار فایل‌های یک پروژه جدید جنگو با نام mysite از دستور زیر استفاده می‌کنیم:django-admin startproject mysiteایجاد یک برنامه (Application) جدید با نام blogبرای ایجاد ساختار فایل‌های یک برنامه جدید به نام blog:python manage.py startapp blogاعمال تمام Migrationهای پایگاه دادهبرای اعمال تمام Migrationها:python manage.py migrateایجاد Migration برای مدل‌های برنامه blogبرای تولید فایل‌های Migration مربوط به مدل‌های برنامه blog:python manage.py makemigrations blogمشاهده دستورات SQL مربوط به اولین Migration برنامه blogبرای مشاهده دستورات SQL که توسط اولین Migration برنامه blog اجرا خواهند شد:python manage.py sqlmigrate blog 0001اجرای سرور توسعه (Development Server)برای اجرای سرور توسعه جنگو:python manage.py runserverاجرای سرور توسعه با مشخص کردن Host، Port و فایل تنظیماتبرای اجرای سرور با Host، Port و فایل تنظیمات دلخواه:python manage.py runserver 127.0.0.1:8001 --settings=mysite.settingsاجرای Django Shellبرای اجرای محیط تعاملی جنگو (Django Shell):python manage.py shellایجاد یک Superuserبرای ایجاد یک کاربر مدیر (Superuser) با استفاده از سیستم احراز هویت جنگو:python manage.py createsuperuserبرای مشاهده فهرست کامل دستورات مدیریتی موجود، به مستندات رسمی جنگو مراجعه کنید:https://docs.djangoproject.com/en/5.0/ref/django-admin/خلاصه فصلدر این فصل، با مبانی فریم‌ورک وب Django از طریق ساخت یک برنامه ساده وبلاگ آشنا شدید.در طول این فصل:مدل‌های داده (Models) را طراحی کردید.Migrationها را ایجاد و روی پایگاه داده اعمال کردید.Viewهای برنامه را ایجاد کردید.Templateها را نوشتید.URLهای برنامه را تعریف کردید.در فصل بعد، قابلیت‌های بیشتری به وبلاگ اضافه خواهید کرد. از جمله:ایجاد Canonical URL برای پست‌هاساخت URLهای سازگار با SEOپیاده‌سازی Pagination برای نمایش صفحه‌بندی اشیاآشنایی با Class-Based Views (CBV)ایجاد فرم‌هایی که به کاربران اجازه می‌دهد:پست‌ها را از طریق ایمیل به دیگران پیشنهاد دهند.برای پست‌ها نظر (Comment) ثبت کنند.غیرههمچنین سورس کد پروژه این فصل(فصل اول) رو میتونید از صفحه گیتهاب داشته باشید:https://github.com/PacktPublishing/Django-5-by-example/tree/main/Chapter01پست قبلی: (۱.۱۴: ایجاد صفحه نمایش و مسیر URL برای پست ها)پست بعدی: (۲.۰: شروع فصل دوم و مقدمات فصل)</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Mon, 06 Jul 2026 01:40:05 +0330</pubDate>
            </item>
                    <item>
                <title>۱.۱۴: ایجاد صفحه نمایش و مسیر URL برای پست ها | ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/%DB%B1%DB%B1%DB%B4-%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF-%D8%B5%D9%81%D8%AD%D9%87-%D9%86%D9%85%D8%A7%DB%8C%D8%B4-%D9%88-%D9%85%D8%B3%DB%8C%D8%B1-url-%D8%A8%D8%B1%D8%A7%DB%8C-%D9%BE%D8%B3%D8%AA-%D9%87%D8%A7-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-django-5-by-example-wde0iqllsix1</link>
                <description>ساخت نمایشگر | Viewهای فهرست و جزئیات (List Views و Detail)اکنون که نحوه استفاده از ORM را یاد گرفتهاید، آماده هستید تا Viewهای برنامه وبلاگ را ایجاد کنید.در جنگو، View تنها یک تابع پایتون است که یک درخواست وب (Web Request) را دریافت کرده و یک پاسخ وب (Web Response) را برمیگرداند. تمام منطق لازم برای تولید پاسخ موردنظر در داخل View قرار میگیرد.ابتدا Viewهای برنامه را ایجاد میکنید، سپس برای هر View یک الگوی URL تعریف میکنید و در نهایت قالبهای HTML را برای نمایش دادههای تولیدشده توسط Viewها میسازید. هر View یک Template را رندر کرده، متغیرهای لازم را به آن ارسال میکند و در نهایت یک پاسخ HTTP شامل خروجی رندرشده را برمیگرداند.ایجاد Viewهای فهرست و جزئیاتابتدا یک View برای نمایش فهرست پستها ایجاد میکنیم.فایل views.py مربوط به برنامه blog را ویرایش کنید تا به شکل زیر درآید:from django.shortcuts import render
from .models import Post

def post_list(request):
    posts = Post.published.all()

    return render(
        request,
        &#039;blog/post/list.html&#039;,
        {&#039;posts&#039;: posts}
    )این اولین View ما در جنگو است.تابع post_list تنها یک پارامتر به نام request دریافت میکند. این پارامتر برای تمام Viewهای جنگو الزامی است.در این View، تمام پستهایی که وضعیت PUBLISHED دارند را با استفاده از Manager سفارشی published که قبلاً ایجاد کردیم، بازیابی میکنیم.در پایان، از میانبر (shortcut) تابع ()render که توسط جنگو فراهم شده است استفاده میکنیم تا فهرست پستها را با Template مشخصشده رندر کنیم.تابع ()render سه آرگومان اصلی دریافت میکند:شیء requestمسیر Templateمتغیرهای Context که باید به Template ارسال شوند.این تابع یک شیء HttpResponse شامل متن رندرشده (که معمولاً کد HTML است) برمیگرداند.میانبر ()render همچنین Request Context را نیز در نظر میگیرد؛ بنابراین هر متغیری که توسط Template Context Processorها تنظیم شده باشد، در Template قابل دسترسی خواهد بود.Context Processorها تنها توابعی هستند که متغیرهایی را به Context قالب اضافه میکنند. در فصل چهارم (Building a Social Website) با نحوه استفاده از آنها آشنا خواهید شد.اکنون یک View دیگر برای نمایش یک پست منفرد ایجاد میکنیم.تابع زیر را به فایل views.py اضافه کنید:from django.http import Http404

def post_detail(request, id):
    try:
        post = Post.published.get(id=id)
    except Post.DoesNotExist:
        raise Http404(&quot;No Post found.&quot;)

    return render(
        request,
        &#039;blog/post/detail.html&#039;,
        {&#039;post&#039;: post}
    )این View با نام post_detail شناخته میشود.این View شناسه (id) یک پست را به عنوان آرگومان دریافت میکند.در داخل View تلاش میکنیم با فراخوانی متد ()get. روی Manager published، شیء Post مربوط به آن شناسه را بازیابی کنیم.اگر هیچ نتیجهای پیدا نشود، استثنای Post.DoesNotExist رخ میدهد که در این حالت یک استثنای Http404 ایجاد میکنیم تا پاسخ HTTP 404 (Not Found) به کاربر برگردانده شود.در پایان نیز با استفاده از تابع ()render پست بازیابیشده را توسط Template مربوطه نمایش میدهیم.استفاده از شورتکات get_object_or_404جنگو میانبری در اختیار ما قرار میدهد که متد ()get. را روی یک Model Manager اجرا کرده و در صورت پیدا نشدن شیء، بهجای ایجاد استثنای DoesNotExist، مستقیماً استثنای Http404 را ایجاد میکند.فایل views.py را ویرایش کرده، get_object_or_404 را وارد (import) کنید و View post_detail را به شکل زیر تغییر دهید:from django.shortcuts import get_object_or_404, render

# ...

def post_detail(request, id):
    post = get_object_or_404(
        Post,
        id=id,
        status=Post.Status.PUBLISHED
    )

    return render(
        request,
        &#039;blog/post/detail.html&#039;,
        {&#039;post&#039;: post}
    )اکنون در View جزئیات، از میانبر ()get_object_or_404 برای بازیابی پست موردنظر استفاده میکنیم.این تابع شیئی را که با پارامترهای دادهشده مطابقت دارد بازیابی میکند و اگر هیچ شیئی یافت نشود، یک خطای HTTP 404 (Not Found) ایجاد میکند.افزودن الگوهای URL برای Viewهاالگوهای URL امکان نگاشت (Mapping) آدرسهای اینترنتی به Viewها را فراهم میکنند.هر الگوی URL از سه بخش تشکیل شده است:یک الگوی رشتهای (Pattern)یک Viewو در صورت نیاز، یک نام (Name) که امکان ارجاع به URL را در کل پروژه فراهم میکند.جنگو الگوهای URL را به ترتیب بررسی میکند و به محض اینکه اولین الگوی منطبق با URL درخواستشده را پیدا کرد، جستجو متوقف میشود.سپس View مربوط به آن الگو را بارگذاری کرده و آن را اجرا میکند. هنگام اجرای View، یک نمونه از کلاس HttpRequest و همچنین آرگومانهای موقعیتی یا کلیدواژهای استخراجشده از URL به آن ارسال میشوند.در پوشه برنامه blog فایلی با نام urls.py ایجاد کرده و کد زیر را در آن قرار دهید:from django.urls import path
from . import views

app_name = &#039;blog&#039;

urlpatterns = [
    # post views
    path(&#039;&#039;, views.post_list, name=&#039;post_list&#039;),
    path(&#039;&lt;int:id&gt;/&#039;, views.post_detail, name=&#039;post_detail&#039;),
]در این کد، با استفاده از متغیر app_name یک فضای نام (Application Namespace) برای برنامه تعریف میکنید.این کار باعث میشود URLهای هر برنامه بهصورت سازمانیافته مدیریت شوند و هنگام ارجاع به آنها از نام برنامه استفاده کنید.در اینجا با استفاده از تابع path() دو الگوی URL تعریف شده است.الگوی اول هیچ آرگومانی دریافت نمیکند و به View post_list متصل شده است.الگوی دوم به View post_detail متصل است و یک آرگومان به نام id دریافت میکند که باید یک عدد صحیح باشد. این تبدیل توسط Path Converter از نوع int انجام میشود.برای استخراج مقادیر از URL از علامتهای &lt; &gt; استفاده میشود.هر مقداری که به صورت &lt;parameter&gt; تعریف شود، بهصورت پیشفرض به شکل رشته (String) دریافت خواهد شد.برای محدود کردن نوع داده، از Path Converterها استفاده میکنیم؛ مانند:&lt;int:year&gt;که فقط اعداد صحیح را قبول کرده و مقدار را به صورت int به View ارسال میکند.به عنوان مثال:&lt;slug:post&gt;فقط مقادیری را میپذیرد که یک Slug معتبر باشند؛ یعنی رشتهای شامل:حروفاعدادزیرخط (_)خط تیره (-)فهرست کامل Path Converterهای موجود در جنگو را میتوانید در مستندات مشاهده کنید:https://docs.djangoproject.com/en/5.0/topics/http/urls/#path-convertersاگر path() و Path Converterها پاسخگوی نیاز شما نباشند، میتوانید از re_path() استفاده کنید تا الگوهای URL پیچیدهتری را با استفاده از Regular Regex) تعریف نمایید.اطلاعات بیشتر در:https://docs.djangoproject.com/en/5.0/ref/urls/#django.urls.re_pathاگر تاکنون با Regular Expression کار نکردهاید، بهتر است ابتدا راهنمای زیر را مطالعه کنید:https://docs.python.org/3/howto/regex.htmlایجاد یک فایل urls.py مجزا برای هر برنامه، بهترین روش برای قابل استفاده مجدد (Reusable) کردن برنامهها در پروژههای دیگر است.اکنون باید URLهای برنامه blog را در فایل URL اصلی پروژه وارد (Include) کنیم.فایل urls.py موجود در پوشه mysite را به شکل زیر تغییر دهید (کد جدید با Bold مشخص شده است):from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path(&#039;admin/&#039;, admin.site.urls),
    path(&#039;blog/&#039;, include(&#039;blog.urls&#039;, namespace=&#039;blog&#039;)),
]الگوی URL جدیدی که با استفاده از include() تعریف شده است، تمام URLهای تعریفشده در فایل blog.urls را در مسیر /blog قرار میدهد.همچنین این URLها تحت فضای نام (Namespace) blog ثبت میشوند.هر Namespace باید در کل پروژه منحصربهفرد باشد.از این پس میتوانید بهراحتی با استفاده از Namespace و نام URL به این مسیرها ارجاع دهید، مانند:blog:post_listblog:post_detailبرای مطالعه بیشتر درباره Namespaceها به مستندات جنگو مراجعه کنید:https://docs.djangoproject.com/en/5.0/topics/http/urls/#url-namespacesایجاد صفحات نمایش | Template برای نمایشگرهای فهرست و جزئياتاکنون Viewها و الگوهای URL مربوط به برنامه وبلاگ را ایجاد کردهایم.الگوهای URL، آدرسها را به Viewها نگاشت (Map) میکنند و Viewها مشخص میکنند چه دادهای باید به کاربر بازگردانده شود.Templateها نحوه نمایش این دادهها را تعیین میکنند. معمولاً Templateها با استفاده از HTML و زبان قالب (Template Language) جنگو نوشته میشوند.اطلاعات بیشتر درباره زبان قالب جنگو را میتوانید در مستندات زیر مشاهده کنید:https://docs.djangoproject.com/en/5.0/ref/templates/language/اکنون Templateهایی را به برنامه اضافه میکنیم تا پستها به شکلی مناسب و کاربرپسند نمایش داده شوند.ساختار Templateهادر پوشه برنامه blog، ساختار زیر را ایجاد کنید:templates/
    blog/
        base.html
        post/
            list.html
            detail.htmlاین ساختار فایلهای Template برنامه را تشکیل میدهد.فایل base.html ساختار اصلی HTML وبسایت را در خود نگه میدارد و صفحه را به دو بخش تقسیم میکند:محتوای اصلی (Main Content)نوار کناری (Sidebar)فایلهای list.html و detail.html از base.html ارثبری میکنند تا بهترتیب View فهرست پستها و View جزئیات یک پست را نمایش دهند.زبان Template جنگوجنگو دارای یک زبان قالب قدرتمند است که مشخص میکند دادهها چگونه نمایش داده شوند.این زبان بر سه مفهوم اصلی استوار است:۱. Template TagTemplate Tagها کنترل میکنند که Template چگونه رندر شود.{% tag %}۲. Template Variableمتغیرهای Template هنگام رندر شدن با مقدار واقعی خود جایگزین میشوند.{{ variable }}۳. Template FilterFilterها امکان تغییر یا قالببندی مقدار متغیرها را قبل از نمایش فراهم میکنند.{{ variable|filter }}تمام Tagها و Filterهای داخلی جنگو در مستندات زیر موجود هستند:https://docs.djangoproject.com/en/5.0/ref/templates/builtins/ایجاد Template پایه (Base Template)فایل base.html را ویرایش کرده و کد زیر را در آن قرار دهید:{% load static %}

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;{% block title %}{% endblock %}&lt;/title&gt;

    &lt;link href=&quot;{% static &quot;css/blog.css&quot; %}&quot; rel=&quot;stylesheet&quot;&gt;
&lt;/head&gt;

&lt;body&gt;

&lt;div id=&quot;content&quot;&gt;
    {% block content %}
    {% endblock %}
&lt;/div&gt;

&lt;div id=&quot;sidebar&quot;&gt;
    &lt;h2&gt;My blog&lt;/h2&gt;
    &lt;p&gt;This is my blog.&lt;/p&gt;
&lt;/div&gt;

&lt;/body&gt;
&lt;/html&gt;{% load static %}عبارت بالا به جنگو اعلام میکند که Template Tagهای مربوط به فایلهای Static را که توسط برنامه django.contrib.staticfiles ارائه شدهاند بارگذاری کند.این برنامه در تنظیمات INSTALLED_APPS قرار دارد.پس از بارگذاری، میتوانید در سراسر Template از Tag زیر استفاده کنید:{% static %}این Tag برای درج فایلهای استاتیک مانند:فایلهای CSSتصاویرفایلهای JavaScriptبه کار میرود.در این مثال از آن برای بارگذاری فایل زیر استفاده شده است:css/blog.cssاین فایل در پوشه static/ برنامه قرار دارد.برای اعمال استایلها، پوشه static/ موجود در کدهای همراه کتاب را در محل مناسب پروژه خود کپی کنید.محتویات آن در این آدرس قرار دارد:https://github.com/PacktPublishing/Django-5-by-example/tree/master/Chapter01/mysite/blog/staticدر این Template دو Tag از نوع block مشاهده میکنید:{% block title %}و{% block content %}این Tagها به جنگو اعلام میکنند که این قسمتها در Templateهای فرزند قابل جایگزینی هستند.بنابراین هر Template که از base.html ارثبری کند، میتواند محتوای این دو بخش را تغییر دهد.ایجاد Template فهرست پستهافایل post/list.html را به شکل زیر ویرایش کنید:{% extends &quot;blog/base.html&quot; %}

{% block title %}
My Blog
{% endblock %}

{% block content %}

&lt;h1&gt;My Blog&lt;/h1&gt;

{% for post in posts %}

&lt;h2&gt;
    &lt;a href=&quot;{% url &#039;blog:post_detail&#039; post.id %}&quot;&gt;
        {{ post.title }}
    &lt;/a&gt;
&lt;/h2&gt;

&lt;p class=&quot;date&quot;&gt;
    Published {{ post.publish }} by {{ post.author }}
&lt;/p&gt;

{{ post.body|truncatewords:30|linebreaks }}

{% endfor %}

{% endblock %}با استفاده از Tag زیر:{% extends &quot;blog/base.html&quot; %}به جنگو اعلام میکنیم که این Template از blog/base.html ارثبری میکند.سپس Blockهای title و content را با محتوای موردنظر پر میکنیم.در داخل Block محتوا، روی مجموعه posts حلقه میزنیم و برای هر پست موارد زیر را نمایش میدهیم:عنوانتاریخ انتشارنویسندهمتن پستهمچنین عنوان هر پست به صفحه جزئیات همان پست لینک شده است.استفاده از Tag urlبرای ساخت لینک از Template Tag زیر استفاده شده است:{% url &#039;blog:post_detail&#039; post.id %}این Tag بهصورت پویا (Dynamic) URLها را بر اساس نام آنها تولید میکند.در اینجا:blog نام Namespace برنامه است.post_detail نام URL تعریفشده در فایل urls.py است.post.id نیز پارامتر لازم برای ساخت URL را فراهم میکند.نکته مهمهمیشه برای ساخت URL در Templateها از Tag زیر استفاده کنید:{% url %}و هرگز آدرسها را بهصورت ثابت (Hardcoded) ننویسید.این کار باعث میشود در آینده اگر ساختار URLها تغییر کرد، نیازی به تغییر Templateها نداشته باشید و نگهداری پروژه بسیار آسانتر شود.استفاده از Filterهادر بدنه پست از دو Filter استفاده شده است:{{ post.body|truncatewords:30|linebreaks }}Filter اول: truncatewordsاین Filter متن را به تعداد مشخصی از کلمات محدود میکند.در اینجا:truncatewords:30تنها ۳۰ کلمه اول متن نمایش داده میشود.Filter دوم: linebreaksاین Filter کاراکترهای شکست خط (n\) را به تگهای HTML مناسب مانند &lt;p&gt; و &lt;br&gt; تبدیل میکند تا متن در مرورگر بهدرستی نمایش داده شود.به یاد داشته باشید:میتوانید هر تعداد Filter که نیاز دارید پشت سر هم قرار دهید.خروجی هر Filter، ورودی Filter بعدی خواهد بود.اجرای برنامهاکنون وضعیت (Status) اولین پست را به منتشر شده | Published تغییر دهید (مطابق شکل زیر):سپس چند پست جدید نیز با وضعیت Published ایجاد کنید تا در صفحه فهرست وبلاگ نمایش داده شوند.ترمینال (Shell) را باز کرده و دستور زیر را برای راهاندازی سرور محیط توسعه اجرا کنید:python manage.py runserverسپس در مرورگر خود آدرس زیر را باز کنید:http://127.0.0.1:8000/blog/اکنون باید برنامه در حال اجرا باشد و صفحه وبلاگ بهدرستی نمایش داده شود.خروجی صفحه باید مشابه تصویر زیر باشد.ایجاد Template جزئیات پست (Post Detail)در مرحله بعد، فایل post/detail.html را به شکل زیر ویرایش کنید:{% extends &quot;blog/base.html&quot; %}

{% block title %}
    {{ post.title }}
{% endblock %}

{% block content %}

&lt;h1&gt;{{ post.title }}&lt;/h1&gt;

&lt;p class=&quot;date&quot;&gt;
    Published {{ post.publish }} by {{ post.author }}
&lt;/p&gt;

{{ post.body|linebreaks }}

{% endblock %}در این Template نیز مانند Template قبلی، از فایل blog/base.html ارثبری میکنیم.سپس مقدار Block title را برابر با عنوان پست (post.title) قرار میدهیم تا عنوان صفحه مرورگر نیز همان عنوان پست باشد.در Block Content نیز اطلاعات پست نمایش داده میشود که شامل موارد زیر است:عنوان پستتاریخ انتشارنویسندهمتن کامل پستبرای نمایش متن پست از Filter زیر استفاده شده است:{{ post.body|linebreaks }}Filter linebreaks کاراکترهای شکست خط (n\) را به تگهای مناسب HTML مانند &lt;p&gt; و &lt;br&gt; تبدیل میکند تا متن با قالببندی صحیح در مرورگر نمایش داده شود.نکته مترجمبه URL صفحه نیز دقت کنید؛ این آدرس باید شامل شناسه (ID) خودکار پست باشد، مانند:/blog/1/در این مثال، عدد 1 شناسه (Primary Key) پستی است که در حال مشاهده آن هستید. اگر روی پست دیگری کلیک کنید، این عدد به شناسه همان پست تغییر خواهد کرد؛ برای مثال:/blog/2/یا:/blog/5/این رفتار به این دلیل است که در فایل urls.py الگوی زیر را تعریف کردهایم:path(&#039;&lt;int:id&gt;/&#039;, views.post_detail, name=&#039;post_detail&#039;)در این الگو، بخش &lt;int:id&gt; مقدار عددی موجود در URL را استخراج کرده و آن را بهصورت آرگومان id به تابع post_detail ارسال میکند. سپس View با استفاده از این شناسه، پست مربوطه را از پایگاه داده بازیابی کرده و نمایش میدهد.پست قبلی: (۱.۱۴: تنظیم url صفحات و ایجاد صفحه نمایش پست های وبلاگ)پست بعدی: (۱.۱۵: یادگیری چرخه عمر Request/Response در جنگو)</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Mon, 06 Jul 2026 01:10:46 +0330</pubDate>
            </item>
                    <item>
                <title>۱.۱۳: ایجاد Model Manager سفارشی | ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/%DB%B1%DB%B1%DB%B3-%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF-model-manager-%D8%B3%D9%81%D8%A7%D8%B1%D8%B4%DB%8C-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-django-5-by-example-yfbqn1phnsag</link>
                <description>اپیزود 13 فصل اول ترجمه کتاب Django 5 By Example اثر Antonio Meleمدل منیجر | Model Manager چیست؟مدل منیجر پیش‌فرض برای هر مدل، objects است. این مدیر تمام آبجکت‌های موجود در دیتابیس را بازیابی می‌کند. با این حال، ما می‌توانیم برای مدل‌ها، مدیرهای سفارشی (Custom Managers) تعریف کنیم.ایجاد مدل منیجر سفارشیبیایید یک مدیر سفارشی ایجاد کنیم تا تمام پست‌هایی که دارای وضعیت PUBLISHED هستند را بازیابی کند. برای افزودن یا سفارشی‌سازی مدیرها در مدل، دو روش کلی وجود دارد: می‌توانید متدهای اضافی به یک مدیر موجود اضافه کنید، و یا با تغییر دادن QuerySet اولیه که مدیر برمی‌گرداند، یک مدیر جدید بسازید. روش اول، امکان استفاده از نشان‌گذاری (Notation) به شکل ()Post.objects.my_manager را فراهم می‌کند و روش دوم، امکان استفاده از نشان‌گذاری به شکل ()Post.my_manager.all را به شما می‌دهد.ما برای پیاده‌سازی مدیری که اجازه می‌دهد پست‌ها را با دستور ()Post.published.all بازیابی کنیم، روش دوم را انتخاب می‌کنیم.فایل models.py در اپلیکیشن وبلاگ خود را به صورت زیر ویرایش کنید تا این مدیر سفارشی اضافه شود:class PublishedManager(models.Manager):
    def get_queryset(self):
        return (
            super().get_queryset().filter(status=Post.Status.PUBLISHED)
        )

class Post(models.Model):
    # model fields
    # ...
    objects = models.Manager()      # مدیر پیش‌فرض (The default manager)
    published = PublishedManager()  # مدیر سفارشی ما (Our custom manager)

    class Meta:
        ordering = [&#039;-publish&#039;]
        indexes = [
            models.Index(fields=[&#039;-publish&#039;]),
        ]

    def __str__(self):
        return self.titleاولین مدل-منیجری که در مدل تعریف می‌شود، تبدیل به مدل-منیجر پیش‌فرض می‌گردد. شما می‌توانید از ویژگی Meta یعنی default_manager_name استفاده کنید تا مدیر پیش‌فرض متفاوتی را مشخص نمایید. اگر هیچ مدیری در مدل تعریف نشود، جنگو به صورت خودکار مدیر objects را برای آن ایجاد می‌کند. اگر هر مدیری برای مدل خود تعریف کنید اما بخواهید objects را نیز حفظ کنید، باید آن را به صورت صریح (Explicit) در مدل خود اضافه نمایید. در کد بالا، ما هم مدیر پیش‌فرض objects و هم مدیر سفارشی published را به مدل Post اضافه کردیم.متد get_queryset() در یک مدیر، QuerySet اجرایی را برمی‌گرداند. ما این متد را بازنویسی (Override) کردیم تا یک QuerySet سفارشی بسازیم که پست‌ها را بر اساس فیلد status فیلتر کند و QuerySet خروجی تنها شامل پست‌هایی با وضعیت PUBLISHED باشد.اکنون که مدیر سفارشی را برای مدل Post تعریف کردیم، بیایید آن را تست کنیم!سرور توسعه را مجدداً با دستور زیر در محیط shell اجرا کنید:python manage.py shellحال می‌توانید مدل Post را import کرده و با اجرای QuerySet زیر، تمام پست‌های منتشر شده‌ای که عنوان آن‌ها با “Who” شروع می‌شود را بازیابی کنید:&gt;&gt;&gt; from blog.models import Post
&gt;&gt;&gt; Post.published.filter(title__startswith=&#039;Who&#039;)برای دریافت نتیجه در این QuerySet، اطمینان حاصل کنید که در آبجکت Post که عنوان آن با عبارت “Who” شروع می‌شود، فیلد status را بر روی PUBLISHED تنظیم کرده باشید.پست قبلی: (۱.۱۲: کار با QuerySet و جستجو در پایگاه داده)پست بعدی: (۱.۱۴: تنظیم url صفحات و ایجاد صفحه نمایش پست های وبلاگ)</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Mon, 06 Jul 2026 00:00:05 +0330</pubDate>
            </item>
                    <item>
                <title>۱.۱۲: کار با QuerySet و جستجو در پایگاه داده | ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/%DB%B1%DB%B1%DB%B2-%DA%A9%D8%A7%D8%B1-%D8%A8%D8%A7-queryset-%D9%88-lookup-%D9%87%D8%A7-%D8%AF%D8%B1-%D8%AC%D9%86%DA%AF%D9%88-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-django-5-by-example-xsqu6lleq7og</link>
                <description>ترجمه کتاب Django 5 By Example - کار با کوئری ست ها در جنگوQuerySet دقیقا چیست و چه وظیفه ای بر عهده دارد؟حالا که یک پنل مدیریت کاملاً کاربردی برای مدیریت پست‌های بلاگ داریم، زمان مناسبی است که بیاموزیم چگونه به صورت برنامه‌نویسی‌شده (Programmatically) داده‌ها را در پایگاه داده بخوانیم و بنویسیم.ORM جنگو، یک API قدرتمند برای انتزاع پایگاه داده است که به شما امکان می‌دهد آبجکت‌ها را به آسانی ایجاد، بازیابی، به‌روزرسانی و حذف کنید. ORM به شما اجازه می‌دهد تا کوئری‌های SQL را با استفاده از پارادایم شیءگرا در پایتون تولید کنید. می‌توانید آن را روشی برای تعامل با پایگاه داده به سبک پایتونی (Pythonic) در نظر بگیرید، بدون اینکه نیاز باشد کوئری‌های خام SQL بنویسید.ORM مدل‌های شما را به جداول پایگاه داده نگاشت می‌کند و یک رابط پایتونی ساده برای تعامل با دیتابیس در اختیارتان قرار می‌دهد. ORM کوئری‌های SQL را تولید کرده و نتایج را به آبجکت‌های مدل نگاشت می‌کند. این ابزار با MySQL، PostgreSQL، SQLite، Oracle و MariaDB سازگار است.به یاد داشته باشید که می‌توانید پایگاه داده پروژه خود را در تنظیمات DATABASES داخل فایل settings.py تعریف کنید. جنگو می‌تواند همزمان با چندین پایگاه داده کار کند و شما می‌توانید Routerهای دیتابیس را برای ایجاد طرح‌های مسیریابی داده اختصاصی برنامه‌نویسی کنید.پس از ایجاد مدل‌های داده، جنگو یک API رایگان برای تعامل با آن‌ها به شما می‌دهد. می‌توانید مستندات رسمی مربوط به API مدل‌ها را در آدرس https://docs.djangoproject.com/en/5.0/ref/models/ مطالعه کنید.ORM جنگو بر پایه QuerySetها بنا شده است. یک QuerySet مجموعه‌ای از کوئری‌های پایگاه داده برای بازیابی آبجکت‌ها از دیتابیس است. شما می‌توانید فیلترهایی را روی QuerySetها اعمال کنید تا نتایج کوئری را بر اساس پارامترهای مشخص محدود کنید. QuerySet معادل عبارت SELECT در SQL است و فیلترها شروط و محدودکننده‌هایی مانند WHERE یا LIMIT محسوب می‌شوند.در ادامه می‌آموزید که چگونه QuerySetها را بسازید و اجرا کنید.ایجاد آبجکت‌هابرای باز کردن شل پایتون، دستور زیر را در ترمینال اجرا کنید:python manage.py shellسپس خطوط زیر را وارد کنید:&gt;&gt;&gt; from django.contrib.auth.models import User
&gt;&gt;&gt; from blog.models import Post
&gt;&gt;&gt; user = User.objects.get(username=&#039;admin&#039;)
&gt;&gt;&gt; post = Post(title=&#039;Another post&#039;,
             slug=&#039;another-post&#039;,
             body=&#039;Post body.&#039;,
             author=user)
&gt;&gt;&gt; post.save()بیایید عملکرد این کد را تحلیل کنیم:ابتدا، آبجکت کاربر با نام کاربری admin را بازیابی می‌کنیم:user = User.objects.get(username=&#039;admin&#039;)متد get() به ما امکان می‌دهد یک آبجکت تکی را از پایگاه داده بازیابی کنیم. این متد در پشت صحنه یک دستور SELECT اجرا می‌کند. توجه داشته باشید که این متد انتظار دارد دقیقاً یک نتیجه منطبق با کوئری پیدا کند. اگر دیتابیس هیچ نتیجه‌ای برنگرداند، این متد استثنای DoesNotExist و اگر بیش از یک نتیجه برگرداند، استثنای MultipleObjectsReturned را پرتاب می‌کند. هر دوی این استثناها ویژگی‌های کلاس مدلی هستند که کوئری روی آن انجام می‌شود.سپس یک نمونه از Post با عنوان، اسلاگ و بدنه سفارشی ایجاد می‌کنیم و کاربری که قبلاً بازیابی کردیم را به عنوان نویسنده پست قرار می‌دهیم. این آبجکت در حافظه (RAM) قرار دارد و هنوز در دیتابیس ذخیره نشده است.در نهایت، با استفاده از متد save()، آبجکت Post را در دیتابیس ذخیره می‌کنیم. این کار در پشت صحنه دستور INSERT را اجرا می‌کند.شما می‌توانید ایجاد و ذخیره آبجکت را در یک مرحله با استفاده از متد create() نیز انجام دهید:&gt;&gt;&gt; Post.objects.create(title=&#039;One more post&#039;,
                     slug=&#039;one-more-post&#039;,
                     body=&#039;Post body.&#039;,
                     author=user)در شرایطی که نیاز دارید آبجکتی را از دیتابیس بگیرید یا اگر وجود نداشت آن را بسازید، متد get_or_create() کارآمد است. این متد یک تاپل شامل آبجکت بازیابی‌شده (یا ایجاد شده) و یک مقدار بولی (Boolean) که نشان می‌دهد آیا آبجکت جدید ساخته شده است یا خیر، برمی‌گرداند.به‌روزرسانی آبجکت‌هاکافی است ویژگی‌های آبجکت را تغییر داده و دوباره save() را فراخوانی کنید:&gt;&gt;&gt; post.title = &#039;New title&#039;
&gt;&gt;&gt; post.save()این بار متد save() دستور UPDATE را در SQL اجرا می‌کند.بازیابی آبجکت‌هاهر مدل جنگو حداقل یک Manager دارد و مدیر پیش‌فرض objects نامیده می‌شود. برای دریافت تمام آبجکت‌ها از یک جدول، از متد all() استفاده می‌کنیم:all_posts = Post.objects.all()نکته کلیدی اینجاست: QuerySetها تنبل (Lazy) هستند. یعنی تا زمانی که مجبور به اجرا نشوند، کوئری به دیتابیس ارسال نمی‌کنند. این ویژگی باعث بهره‌وری بالای ORM می‌شود.فیلتر کردن آبجکت‌هابرای فیلتر کردن یک QuerySet، از متد filter() استفاده می‌کنیم که به شما اجازه می‌دهد محتوای عبارت WHERE در SQL را مشخص کنید. (در شل وارد کنید):Post.objects.filter(title=&#039;Who was Django Reinhardt?&#039;)نکته: تغییراتی که روی یک مدل اعمال می‌کنید تا زمانی که متد save() را فراخوانی نکنید، در دیتابیس ثبت نمی‌شوند.با چاپ کردن ویژگی query از یک QuerySet، می‌توانید دستور SQL تولید شده توسط جنگو را مشاهده کنید:خروجی SQL نشان می‌دهد که یک جستجوی دقیق (Exact match) روی ستون title انجام شده و به دلیل اینکه ترتیب خاصی مشخص نکردیم، از گزینه پیش‌فرض ordering در تنظیمات Meta مدل استفاده شده است.&gt;&gt;&gt; posts = Post.objects.filter(title=&#039;Who was Django Reinhardt?&#039;)
&gt;&gt;&gt; print(posts.query) # &lt;- query اتریبیوتبا چاپ اتریبیوت query از کوئری-ست دریافتی، میتوان کد SQL تولید شده توسط جنگو را مشاهده کرد که در ادامه خواهید دید:SELECT &quot;blog_post&quot;.&quot;id&quot;, &quot;blog_post&quot;.&quot;title&quot;, &quot;blog_post&quot;.&quot;slug&quot;, &quot;blog_
post&quot;.&quot;author_id&quot;, &quot;blog_post&quot;.&quot;body&quot;, &quot;blog_post&quot;.&quot;publish&quot;, &quot;blog_
post&quot;.&quot;created&quot;, &quot;blog_post&quot;.&quot;updated&quot;, &quot;blog_post&quot;.&quot;status&quot; FROM &quot;blog_post&quot;
WHERE &quot;blog_post&quot;.&quot;title&quot; = Who was Django Reinhardt? ORDER BY &quot;blog_
post&quot;.&quot;publish&quot; DESCانواع جستجو در QuerySet:در این بخش از پست به بررسی QuerySetها در جنگو (Django) و انواع مختلف lookup یا الگوهای جستجو می‌پردازیم.مثال پیشینِ QuerySet شامل یک فیلترِ جستجو (Lookup) با تطابق دقیق (Exact match) بود. رابطِ QuerySet انواع مختلفی از جستجوها را در اختیار شما قرار می‌دهد. برای تعریف نوع جستجو از دو آندرلاین استفاده می‌شود، که فرمت آن به صورت field__lookup است. برای نمونه، دستور زیر یک تطابق دقیق ایجاد می‌کند:1) جستجوی دقیقبرای جستجوی دقیق از __exact استفاده می‌شود:Post.objects.filter(id__exact=1)اگر نوع جستجو را مشخص نکنید، جنگو به‌صورت پیش‌فرض exact را فرض می‌کند:Post.objects.filter(id=1)2) جستجوی دقیق بدون حساسیت به حروفبرای جستجوی دقیق بدون حساسیت به حروف کوچک و بزرگ از __iexact استفاده می‌شود:Post.objects.filter(title__iexact=&#039;who was django reinhardt?&#039;)3) جستجوی شاملبرای بررسی اینکه یک مقدار داخل مقدار فیلد وجود دارد از contains__ استفاده می‌شود. این lookup به SQL LIKE ترجمه می‌شود:WHERE title LIKE &#039;%Django%&#039;
نسخه بدون حساسیت به حروف آن نیز با icontains__ در دسترس است.4) جستجو در یک مجموعهبرای بررسی وجود یک مقدار در یک iterable مانند لیست، tuple یا حتی یک QuerySet دیگر از __in استفاده می‌شود:Post.objects.filter(id__in=[1, 3])5) عملگرهای مقایسه‌ایاین lookupها برای مقایسه عددی و ترتیبی استفاده می‌شوند:بزرگ‌تر از: gt__Post.objects.filter(id__gt=3)معادل:... WHERE id &gt; 3بزرگ‌تر یا مساوی: gte__کوچک‌تر از: lt__کوچک‌تر یا مساوی: lte__6) جستجو با شروع/پایان متنبرای تطبیق ابتدای یا انتهای رشته:startswith__istartswith__endswith__iendswith__7) جستجوهای مبتنی بر تاریخمی‌توانید بر اساس اجزای مختلف یک DateTimeField یا DateField جستجو کنید:Post.objects.filter(publish__date=date(2024, 1, 31))
Post.objects.filter(publish__year=2024)
Post.objects.filter(publish__month=1)
Post.objects.filter(publish__day=1)
Post.objects.filter(publish__date__gt=date(2024, 1, 1))
جستجو روی فیلدهای مرتبطبا استفاده از دو آندرلاین (__) می‌توان روی فیلدهای مدل‌های مرتبط هم فیلتر اعمال کرد. (مثل کلید خارجی یا 1:M):Post.objects.filter(author__username=&#039;admin&#039;)همچنین می‌توان جستجو در مدل مرتبط را زنجیره‌ای کرد:Post.objects.filter(author__username__istartswith=&#039;ad&#039;)و حتی چند شرط را همزمان اعمال کرد:Post.objects.filter(publish__year=2024, author__username=&#039;admin&#039;)زنجیره‌ای کردن فیلترهانتیجه‌ی filter() خودش یک QuerySet دیگر است، بنابراین می‌توان فیلترها را زنجیره‌ای کرد:Post.objects.filter(publish__year=2024) \
    .filter(author__username=&#039;admin&#039;)حذف نتایج با ()excludeبرای حذف برخی نتایج از QuerySet از ()exclude استفاده می‌شود:Post.objects.filter(publish__year=2024) \
    .exclude(title__startswith=&#039;Why&#039;)مرتب‌سازی آبجکت‌هامرتب‌سازی پیش‌فرض در گزینه ordering در کلاس Meta مدل تعریف می‌شود.برای تغییر ترتیب از ()order_by استفاده می‌کنیم:صعودی:Post.objects.order_by(&#039;title&#039;)نزولی:Post.objects.order_by(&#039;-title&#039;)بر اساس چند فیلد:Post.objects.order_by(&#039;author&#039;, &#039;title&#039;)ترتیب تصادفی:Post.objects.order_by(&#039;?&#039;)محدود کردن QuerySetهامی‌توان با syntax برش آرایه‌ای (slicing) تعداد نتایج را محدود کرد:Post.objects.all()[:5]این معادل SQL LIMIT 5 است.مثال دیگر:Post.objects.all()[3:6]این مورد معادل دریافت اشیای چهارم تا ششم است و از نظر SQL به OFFSET و LIMIT ترجمه می‌شود.برای گرفتن یک شیء منفرد نیز می‌توان از index استفاده کرد:Post.objects.order_by(&#039;?&#039;)[0]شمارش اشیاءمتد count() تعداد کل اشیای منطبق با QuerySet را برمی‌گرداند:Post.objects.filter(id__lt=3).count()این معادل SELECT COUNT(*) در SQL است.بررسی وجود داشتن نتیجه کوئریبرای بررسی اینکه آیا QuerySet نتیجه‌ای دارد یا نه از ()exists استفاده می‌شود:Post.objects.filter(title__startswith=&#039;Why&#039;).exists()خروجی این متد True یا False است.حذف اشیاءبرای حذف یک نمونه از متد ()delete استفاده می‌شود:post = Post.objects.get(id=1)
post.delete()توجه داشته باشید که حذف یک آبجکت می‌تواند آبجکت‌های وابسته را هم حذف کند، به‌خصوص وقتی فیلدهای ForeignKey با on_delete=models.CASCADE تعریف شده باشند.جستجوهای پیچیده به وسیله Q objectفیلترهای ()filter به‌صورت پیش‌فرض با AND در SQL ترکیب می‌شوند.برای ساخت شرط‌های پیچیده‌تر، مثل OR، از Q object استفاده می‌شود.Q object مجموعه‌ای از جستجوها | lookup را کپسوله می‌کند و می‌توان آن‌ها را با عملگرهای زیر ترکیب کرد:&amp; برای AND| برای OR^ برای XORمثال:pythonfrom django.db.models import Q

starts_who = Q(title__istartswith=&#039;who&#039;)
starts_why = Q(title__istartswith=&#039;why&#039;)

Post.objects.filter(starts_who | starts_why)
برای اطلاعات بیشتر:https://docs.djangoproject.com/en/5.0/topics/db/queries/#complex-lookups-with-q-objectsزمان ارزیابی QuerySetهاساختن یک QuerySet به‌تنهایی هیچ کوئری‌ای به دیتابیس ارسال نمی‌کند تا زمانی که evaluate شود.ویژگی مهم QuerySetها این است که lazy هستند؛ یعنی تا زمان نیاز واقعی اجرا نمی‌شوند. این باعث می‌شود بتوانید چندین ()filter را زنجیره‌ای کنید بدون اینکه هنوز دیتابیس را hit کنید.QuerySetها معمولاً در موارد زیر ارزیابی می‌شوند:اولین بار که روی آن‌ها iterate می‌کنیدهنگام slicing مثل:Post.objects.all()[:3]هنگام pickle یا cache کردنهنگام فراخوانی ()repr یا ()lenهنگام تبدیل صریح به ()listهنگام استفاده در شرط‌های بولی مانند ()bool، or، and یا ifپست قبلی: (۱.۱۱: اضافه کردن آیکون شمارنده به فیلترها)پست بعدی: (۱.۱۳: ایجاد Model Manager و شخصی سازی آن)</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Sat, 04 Jul 2026 18:15:42 +0330</pubDate>
            </item>
                    <item>
                <title>۱.۱۱ - اضافه کردن آیکون شمارنده به فیلترها | ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/%DB%B1%DB%B1%DB%B1-%D8%A7%D8%B6%D8%A7%D9%81%D9%87-%DA%A9%D8%B1%D8%AF%D9%86-%D8%A2%DB%8C%DA%A9%D9%88%D9%86-%D8%B4%D9%85%D8%A7%D8%B1%D9%86%D8%AF%D9%87-%D8%A8%D9%87-%D9%81%DB%8C%D9%84%D8%AA%D8%B1%D9%87%D8%A7-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-django-5-by-example-uvbus48zobby</link>
                <description>آیکون شمارنده یا همان Facet counts: این ویژگی جدیدی است که در جنگو ۵ معرفی شده است و در این پست قصد داریم با آن آشنا شویم و از آن بهره ببریم.ترجمه کتاب جنگو ۵ با مثال - فصل اول - اپیزود ۱۱ - اضافه کردن آیکون شمارنده به فیلترهاجنگو ۵.۰ قابلیت آیکون شمارنده | Facet Counts را به پنل مدیریت (Admin Site) اضافه کرده است که تعداد نتایج هر فیلتر را نمایش می‌دهد که.این تعدادها نشان می‌دهند که برای هر گزینه‌ی فیلتر، چه تعداد شیء (Object) وجود دارد. به این ترتیب، هنگام مشاهده‌ی صفحه‌ی لیست رکوردها (Change List) در بخش مدیریت، راحت‌تر می‌توان تشخیص داد که هر فیلتر چه تعداد نتیجه دارد.در ادامه، تنظیم می‌کنیم که Facet Counts همیشه برای مدل مدیریتی PostAdmin نمایش داده شوند.فایل admin.py برنامه‌ی blog را ویرایش کرده و خطی که با پررنگ مشخص شده است را اضافه کنید:from django.contrib import admin
from .models import Post

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_display = [&#039;title&#039;, &#039;slug&#039;, &#039;author&#039;, &#039;publish&#039;, &#039;status&#039;]
    list_filter = [&#039;status&#039;, &#039;created&#039;, &#039;publish&#039;, &#039;author&#039;]
    search_fields = [&#039;title&#039;, &#039;body&#039;]
    prepopulated_fields = {&#039;slug&#039;: (&#039;title&#039;,)}
    raw_id_fields = [&#039;author&#039;]
    date_hierarchy = &#039;publish&#039;
    ordering = [&#039;status&#039;, &#039;publish&#039;]
    show_facets = admin.ShowFacets.ALWAYSهمچنین دو گزینه دیگر ALLOW. و NEVER. هم وجود دارد که مشهود است.اکنون با استفاده از پنل مدیریت، چند Post ایجاد کنید و سپس به آدرس زیر بروید:http://127.0.0.1:8000/admin/blog/post/اکنون باید در کنار گزینه‌های فیلتر، تعداد رکوردهای مربوط به هر گزینه نیز نمایش داده شود؛ همان‌طور که در شکل زیر مشاهده می‌کنید.نتیجه Facet Filters و گزینه ALWAYS در نسخه جنگو ۵شکل ۱.۱۵: فیلترهای فیلد Status همراه با تعداد (Facet Counts)تنها با چند خط کد، نحوه‌ی نمایش این مدل در پنل مدیریت را سفارشی‌سازی کردیم. روش‌های بسیار زیادی برای شخصی‌سازی و گسترش پنل مدیریت جنگو وجود دارد که در ادامه‌ی این کتاب با آن‌ها آشنا خواهید شد.برای اطلاعات بیشتر درباره‌ی پنل مدیریت جنگو، به مستندات رسمی مراجعه کنید:https://docs.djangoproject.com/en/5.0/ref/contrib/admin/پست قبلی: (۱.۱۰: شخصی سازی و ارتقا پنل ادمین جنگو)پست بعدی: (1.12: کار با QuerySet و جستجو در آن)</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Sat, 04 Jul 2026 01:48:39 +0330</pubDate>
            </item>
                    <item>
                <title>۱.۱۰: شخصی سازی و ارتقا پنل ادمین جنگو | ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/%DB%B1%DB%B1%DB%B0-%D8%B4%D8%AE%D8%B5%DB%8C-%D8%B3%D8%A7%D8%B2%DB%8C-%D9%88-%D8%A7%D8%B1%D8%AA%D9%82%D8%A7-%D9%BE%D9%86%D9%84-%D8%A7%D8%AF%D9%85%DB%8C%D9%86-%D8%AC%D9%86%DA%AF%D9%88-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-django-5-by-example-jdutg5uvokfb</link>
                <description>ادامه ترجمه کتاب Django 5 By Example - فصل اول - قسمت ۱۰شخصی سازی پنل ادمین در جنگواکنون نگاهی خواهیم داشت به اینکه چگونه سایت مدیریت (Administration site) را شخصی‌سازی کنیم. فایل admin.py اپلیکیشن وبلاگ خود را ویرایش کرده و آن را مطابق زیر تغییر دهید.from django.contrib import admin
from .models import Post

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_display = [&#039;title&#039;, &#039;slug&#039;, &#039;author&#039;, &#039;publish&#039;, &#039;status&#039;]ما به سایت مدیریت جنگو می‌گوییم که مدل (Model) با استفاده از یک کلاس سفارشی که از ModelAdmin ارث‌بری می‌کند، در سایت ثبت شده است. در این کلاس، می‌توانیم اطلاعاتی در مورد نحوه نمایش مدل در سایت مدیریت و چگونگی تعامل با آن را اضافه کنیم.ویژگی list_display به شما اجازه می‌دهد فیلدهایی از مدل خود را که می‌خواهید در صفحه لیست اشیاء (Object list page) در مدیریت نمایش داده شوند، تنظیم کنید. دکوریتر @admin.register() همان عملکرد تابع admin.site.register() را که جایگزین کرده‌اید، انجام می‌دهد و کلاس ModelAdminای که دکور شده است را ثبت می‌کند.بیایید مدل ادمین را با گزینه‌های بیشتری شخصی‌سازی کنیم. فایل admin.py اپلیکیشن وبلاگ خود را ویرایش کرده و آن را مطابق زیر تغییر دهید:from django.contrib import admin
from .models import Post

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_display = [&#039;title&#039;, &#039;slug&#039;, &#039;author&#039;, &#039;publish&#039;, &#039;status&#039;]
    list_filter = [&#039;status&#039;, &#039;created&#039;, &#039;publish&#039;, &#039;author&#039;]
    search_fields = [&#039;title&#039;, &#039;body&#039;]
    prepopulated_fields = {&#039;slug&#039;: (&#039;title&#039;,)}
    raw_id_fields = [&#039;author&#039;]
    date_hierarchy = &#039;publish&#039;
    ordering = [&#039;status&#039;, &#039;publish&#039;]به مرورگر خود بازگردید و صفحه لیست پست‌ها را رفرش کنید. اکنون، این صفحه به شکل زیر خواهد بود:لیست نمایش اختصاصی مدل پست در پنل ادمین جنگومی‌توانید مشاهده کنید فیلدهایی که در صفحه لیست پست‌ها نمایش داده می‌شوند، همان‌هایی هستند که ما در ویژگی (attribute) list_display مشخص کرده‌ایم. اکنون صفحه لیست شامل یک نوار کناری (sidebar) در سمت راست است که به شما اجازه می‌دهد نتایج را بر اساس فیلدهای موجود در ویژگی list_filter فیلتر کنید. فیلترهای مربوط به فیلدهای ForeignKey (مانند author) تنها در صورتی در نوار کناری نمایش داده می‌شوند که بیش از یک شیء (object) در پایگاه داده وجود داشته باشد.یک نوار جستجو (search bar) نیز در صفحه ظاهر شده است؛ دلیل این امر آن است که ما فهرستی از فیلدهای قابل جستجو را با استفاده از ویژگی search_fields تعریف کرده‌ایم. درست در زیر نوار جستجو، لینک‌های ناوبری برای پیمایش در یک سلسله‌مراتب زمانی (date hierarchy) قرار دارند؛ این قابلیت توسط ویژگی date_hierarchy تعریف شده است. همچنین مشاهده می‌کنید که پست‌ها به‌صورت پیش‌فرض بر اساس ستون‌های status و publish مرتب شده‌اند. ما معیار مرتب‌سازی پیش‌فرض را با استفاده از ویژگی ordering مشخص کرده‌ایم.در مرحله بعد، روی لینک ADD POST کلیک کنید. در اینجا نیز متوجه تغییراتی خواهید شد: همزمان با تایپ کردن عنوان (title) یک پست جدید، فیلد slug به‌صورت خودکار پر می‌شود. شما با استفاده از ویژگی prepopulated_fields به جنگو گفته‌اید که فیلد slug را با استفاده از ورودیِ فیلد title به‌طور خودکار پیش-پردازش (prepopulate) کند:همچنین، فیلد author اکنون با یک ویجت جستجو (lookup widget) نمایش داده می‌شود که وقتی با هزاران کاربر روبرو هستید، می‌تواند بسیار بهتر از یک منوی کشویی (drop-down) برای انتخاب ورودی عمل کند. این قابلیت با استفاده از ویژگی raw_id_fields محقق شده است و به این شکل به نظر می‌رسد:پست قبلی: (فصل اول - قسمت ۹ ایجاد پنل مدیریت و ایجاد کاربر به عنوان مدیر ارشد)پست بعدی: (فصل اول - اپیزود ۱۱ - اضافه کردن آیکون  شمارنده برای فیلترها - Facet Counts)</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Wed, 01 Jul 2026 01:28:52 +0330</pubDate>
            </item>
                    <item>
                <title>۱.۹: ایجاد پنل مدیریت و ایجاد کاربر به عنوان مدیر ارشد | ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-django-5-by-examplec1-e9-yj2rl0jjvc6l</link>
                <description>ادامه ترجمه کتاب Django 5 By Example - فصل اول - قسمت ۹ایجاد پنل مدیریتاکنون که مدل Post با پایگاه داده همگام‌سازی شده است، می‌توانیم یک سایت مدیریت ساده برای مدیریت پست‌های وبلاگ ایجاد کنیم.جنگو به صورت پیش‌فرض دارای یک رابط کاربری مدیریت (Administration Interface) است که برای ویرایش محتوا بسیار مفید و کاربردی است. سایت مدیریت جنگو به صورت پویا و با خواندن متادیتای مدل‌ها ساخته می‌شود و یک رابط آماده برای بهره‌برداری (production-ready) جهت ویرایش محتوا فراهم می‌کند. شما می‌توانید بدون نیاز به تنظیمات اولیه (out of the box) از آن استفاده کنید یا نحوه نمایش مدل‌های خود را در آن پیکربندی نمایید.برنامه django.contrib.admin به صورت پیش‌فرض در تنظیمات INSTALLED_APPS موجود است، بنابراین نیازی به اضافه کردن دستی آن ندارید.ایجاد مدیر ارشدابتدا باید کاربری ایجاد کنید تا بتواند سایت مدیریت را کنترل کند. دستور زیر را در ترمینال اجرا کنید:python manage.py createsuperuserخروجی زیر را مشاهده خواهید کرد. نام کاربری، ایمیل و رمز عبور دلخواه خود را مطابق نمونه زیر وارد کنید:Username (leave blank to use &#039;admin&#039;): admin
Email address: admin@admin.com
Password: ********
Password (again): ********سپس پیام موفقیت‌آمیز زیر را خواهید دید:Superuser created successfully.ما به همین سادگی یک کاربر مدیر با بالاترین سطح دسترسی ایجاد کردیم.ورود به پنل مدیریت جنگوسرور توسعه (development server) را با دستور زیر اجرا کنید:python manage.py runserverدر مرورگر خود آدرس زیر را باز کنید.http://127.0.0.1:8000/admin/باید صفحه ورود به بخش مدیریت را مطابق شکل زیر مشاهده کنید.با استفاده از مشخصات کاربری (نام کاربری و رمز عبوری) که در مرحله قبل ایجاد کردید، وارد سیستم شوید.سپس صفحه اصلی (Index) سایت مدیریت را مشاهده خواهید کرد، همان‌طور که در شکل زیر نشان داده شده است.مدل‌های Group و User که در اسکرین‌شات قبل مشاهده می‌کنید، بخشی از چارچوب احراز هویت (Authentication Framework) جنگو هستند که در مسیر django.contrib.auth قرار دارند. اگر روی Users کلیک کنید، کاربری را که پیش‌تر ایجاد کرده بودید، مشاهده خواهید کرد.اضافه کردن مدل‌ها به پنل مدیریتبیایید مدل‌های وبلاگ خود را به سایت مدیریت اضافه کنیم. فایل admin.py را در اپلیکیشن blog ویرایش کنید تا به شکل زیر دربیاید:from django.contrib import admin
from .models import Post

admin.site.register(Post)اکنون، صفحه مدیریت را در مرورگر خود رفرش (Reload) کنید. باید مدل Post خود را در سایت، به صورت زیر مشاهده کنید:مدل پست اپلیکیشن جنگو در پنل مدیریت جنگوخیلی ساده بود، نه؟ وقتی یک مدل را در سایت مدیریت جنگو ثبت (Register) می‌کنید، جنگو با استفاده از تکنیک بازبینی مدل (Introspecting models)، یک رابط کاربری کاربرپسند برای شما تولید می‌کند که به شما اجازه می‌دهد اشیاء (Objects) را به شکلی ساده لیست، ویرایش، ایجاد و حذف کنید.برای افزودن یک پست جدید، روی لینک Add که در کنار بخش Posts قرار دارد، کلیک کنید. در اینجا متوجه فرمی خواهید شد که جنگو به‌صورت پویا (Dynamically) برای مدل شما تولید کرده است؛ همان‌طور که در شکل زیر نشان داده شده است:فرم ویرایش مدل پست در پنل مدیریت جنگوجنگو برای هر نوع فیلد، از ویجت‌های فرم (Form Widgets) متفاوتی استفاده می‌کند. حتی فیلدهای پیچیده‌ای مانند DateTimeField نیز با یک رابط کاربری ساده، مانند یک انتخابگر تاریخ مبتنی بر جاوااسکریپت (JavaScript date picker)، نمایش داده می‌شوند.فرم را پر کرده و روی دکمه SAVE کلیک کنید. پس از آن، باید همراه با یک پیام موفقیت (Success message) و پستی که تازه ایجاد کرده‌اید، به صفحه لیست پست‌ها هدایت شوید؛ همان‌طور که در شکل زیر مشاهده می‌شود:نمای لیست (List view) مدل Post در سایت مدیریت جنگو، همراه با پیام موفقیت‌آمیز بودن عملیات.پست قبلی: (فصل اول - اپیزود ۸ - پیاده سازی رابطه یک به چند در مدل کاربر و پست)پست بعدی: (فصل اول - اپیزود ۱۰ - سفارشی سازی نحوه نمایش مدل ها در پنل مدیریت جنگو)</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Tue, 30 Jun 2026 02:43:13 +0330</pubDate>
            </item>
                    <item>
                <title>فصل اول - اپیزود ۸ - ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/%D9%81%D8%B5%D9%84-%D8%A7%D9%88%D9%84-%D8%A7%D9%BE%DB%8C%D8%B2%D9%88%D8%AF-%DB%B8-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-django-5-by-example-pjug8dpjf8dv</link>
                <description>ترجمه کتاب Django 5 By Example اثر آنتونیو مله - فصل ۱ - اپیزود ۸ - پیاده سازی رابطه یک به چند در مدل کاربر و پستپیاده سازی رابطه یک به چند در مدل کاربر و پستپست‌ها همیشه توسط یک نویسنده نوشته می‌شوند. ما رابطه‌ای بین کاربران و پست‌ها ایجاد خواهیم کرد که نشان دهد کدام کاربر، کدام پست‌ها را نوشته است.جنگو همراه با یک فریم‌ورک احراز هویت (Authentication Framework) ارائه می‌شود که حساب‌های کاربری را مدیریت می‌کند. فریم‌ورک احراز هویت جنگو در پکیج django.contrib.auth قرار دارد و شامل یک مدل کاربر (User model) است. برای تعریف رابطه بین کاربران و پست‌ها، ما از تنظیمات AUTH_USER_MODEL استفاده خواهیم کرد که به صورت پیش‌فرض به auth.User اشاره دارد. این تنظیم به شما اجازه می‌دهد تا مدل کاربر متفاوتی را برای پروژه خود مشخص کنید.فایل models.py در اپلیکیشن بلاگ را به گونه‌ای ویرایش کنید که به شکل زیر دربیاید:ما تنظیمات (settings) پروژه را وارد (Import) کرده‌ایم و یک فیلد author (نویسنده) به مدل Post اضافه کرده‌ایم. این فیلد یک رابطه «یک‌-به-چند» (many-to-one) با مدل کاربر پیش‌فرض تعریف می‌کند؛ به این معنی که هر پست توسط یک کاربر نوشته می‌شود و هر کاربر می‌تواند تعداد نامحدودی پست بنویسد. برای این فیلد، جنگو با استفاده از کلید اصلی (Primary Key) مدلِ مرتبط، یک کلید خارجی (Foreign Key) در پایگاه داده ایجاد خواهد کرد.پارامتر on_delete رفتاری را مشخص می‌کند که هنگام حذف شیءِ مورد ارجاع (Referenced Object)، باید اتخاذ شود. این موضوع مختص جنگو نیست، بلکه یک استاندارد SQL است. با استفاده از CASCADE مشخص می‌کنید که وقتی کاربرِ مرتبط حذف شد، پایگاه داده باید تمام پست‌های بلاگ مرتبط با او را نیز حذف کند. می‌توانید تمام گزینه‌های ممکن را در لینک زیر مشاهده کنید:https://docs.djangoproject.com/en/5.0/ref/models/fields/#django.db.models.ForeignKey.on_deleteما از related_name برای مشخص کردن نامِ «رابطه معکوس» (Reverse Relationship)، یعنی از سمت User به Post استفاده می‌کنیم. این کار به ما اجازه می‌دهد تا به راحتی از طریق نحو (Notation) user.blog_posts به اشیاء مرتبط از طریق یک آبجکت کاربر دسترسی پیدا کنیم. در ادامه بیشتر درباره این موضوع خواهیم آموخت.جنگو با انواع مختلفی از فیلدها ارائه می‌شود که می‌توانید از آن‌ها برای تعریف مدل‌های خود استفاده کنید. می‌توانید تمام انواع فیلدها را در این لینک پیدا کنید:https://docs.djangoproject.com/en/5.0/ref/models/fields/اکنون مدل Post کامل شده است و می‌توانیم آن را با پایگاه داده همگام‌سازی (Synchronize) کنیم.نکته مترجم: به یاد داشته باشید که استفاده از settings.AUTH_USER_MODEL به جای ارجاع مستقیم به User یک Best Practice فوق‌العاده در جنگو است. این عادت باعث می‌شود اگر در آینده تصمیم گرفتید مدل کاربر سفارشی خودتان را (مثلاً با اضافه کردن فیلد شماره موبایل یا پروفایل تجاری) پیاده سازی کنید، تمامی پروژه مختل نشود و از هارد-کدینگ جلوگیری میکند و این یک شیوه کدنویسی تمیز(Clean Code) است.ایجاد مایگرشن و اعمال مایگرشن به پایگاه دادهاکنون که یک مدل داده (Data Model) برای پست‌های بلاگ داریم، باید جدول پایگاه داده متناظر با آن را ایجاد کنیم. جنگو همراه با یک سیستم «مهاجرت» (Migration System) ارائه می‌دهد که تغییرات اعمال شده در مدل‌ها را ردیابی کرده و امکان انتشار (Propagate) آن‌ها را در پایگاه داده فراهم می‌کند.دستور migrate مهاجرت‌ها را برای تمام اپلیکیشن‌هایی که در لیست INSTALLED_APPS قرار دارند، اعمال می‌کند. این دستور، پایگاه داده را با مدل‌های فعلی و مهاجرت‌های موجود همگام‌سازی (Synchronize) می‌کند.ابتدا، باید یک مهاجرت اولیه برای مدل Post خود ایجاد کنیم. دستور زیر را در ترمینال (Shell Prompt) از مسیر اصلی (Root) پروژه خود اجرا کنید:python manage.py makemigrations blogخروجی شما باید چیزی شبیه به زیر باشد:Migrations for &#039;blog&#039;:
  blog/migrations/0001_initial.py
    - Create model Post
    - Create index blog_post_publish_bb7600_idx on field(s) (-publish of model post)جنگو به تازگی فایل 0001_initial.py را در دایرکتوری migrations اپلیکیشن blog ایجاد کرده است. این مهاجرت شامل دستورات SQL برای ایجاد جدول پایگاه داده برای مدل Post و تعریف ایندکس (Index) دیتابیس برای فیلد publish است.می‌توانید به محتویات این فایل نگاهی بیندازید تا ببینید مهاجرت چگونه تعریف شده است. یک فایل مهاجرت، وابستگی‌ها (Dependencies) به سایر مهاجرت‌ها و عملیاتی که باید در پایگاه داده برای همگام‌سازی با تغییرات مدل انجام شوند را مشخص می‌کند.بیایید نگاهی به کد SQL بیندازیم که جنگو برای ایجاد جدول مدل شما در پایگاه داده اجرا خواهد کرد. دستور sqlmigrate نام مهاجرت‌ها را می‌گیرد و کد SQL آن‌ها را بدون اجرا کردن، باز می‌گرداند.برای مشاهده خروجی SQL اولین مهاجرت خود، دستور زیر را در ترمینال اجرا کنید:python manage.py sqlmigrate blog 0001خروجی باید به شکل زیر باشد:BEGIN;
--
-- Create model Post
--
CREATE TABLE &quot;blog_post&quot; (
&quot;id&quot; integer NOT NULL PRIMARY KEY AUTOINCREMENT,
&quot;title&quot; varchar(250) NOT NULL,
&quot;slug&quot; varchar(250) NOT NULL,
&quot;body&quot; text NOT NULL,
&quot;publish&quot; datetime NOT NULL,
&quot;created&quot; datetime NOT NULL,
&quot;updated&quot; datetime NOT NULL,
&quot;status&quot; varchar(10) NOT NULL,
&quot;author_id&quot; integer NOT NULL REFERENCES &quot;auth_user&quot; (&quot;id&quot;) DEFERRABLE;
--
-- Create blog_post_publish_bb7600_idx on field(s) (-publish of model post)
--
CREATE INDEX &quot;blog_post_publish_bb7600_idx&quot; ON &quot;blog_post&quot; (&quot;publish&quot; DESC);
CREATE INDEX &quot;blog_post_slug_b95473f2&quot; ON &quot;blog_post&quot; (&quot;slug&quot;);
CREATE INDEX &quot;blog_post_author_id_dd7a8485&quot; ON &quot;blog_post&quot; (&quot;author_id&quot;);
COMMIT;خروجی دقیق بسته به پایگاه داده‌ای که استفاده می‌کنید، متفاوت خواهد بود. خروجی بالا برای SQLite تولید شده است. همانطور که در خروجی مشاهده می‌کنید، جنگو نام جداول را با ترکیب نام اپلیکیشن و نام مدل به صورت حروف کوچک (blog_post) ایجاد می‌کند؛ اما شما همچنین می‌توانید با استفاده از ویژگی db_table در کلاس Meta مدل خود، یک نام سفارشی برای جدول دیتابیس تعیین کنید.جنگو یک ستون id با قابلیت خودکار افزایشی (Auto-incremental) ایجاد می‌کند که به عنوان کلید اصلی (Primary Key) برای هر مدل استفاده می‌شود، اما شما می‌توانید با تعیین primary_key=True روی یکی از فیلدهای مدل خود، این مورد را تغییر دهید (Override کنید). ستون پیش‌فرض id شامل یک عدد صحیح است که به صورت خودکار افزایش می‌یابد. این ستون با فیلد id که به طور خودکار به مدل شما اضافه می‌شود، مطابقت دارد.سه ایندکس دیتابیس زیر ایجاد شده‌اند:یک ایندکس با ترتیب نزولی (Descending) روی ستون publish: این همان ایندکسی است که ما صراحتاً با استفاده از گزینه indexes در کلاس Meta مدل تعریف کردیم.یک ایندکس روی ستون slug: زیرا فیلدهای از نوع SlugField به صورت پیش‌فرض شامل یک ایندکس هستند.یک ایندکس روی ستون author_id: زیرا فیلدهای از نوع ForeignKey به صورت پیش‌فرض شامل یک ایندکس هستند.بیایید مدل Post را با جدول متناظر آن در دیتابیس یعنی blog_post مقایسه کنیم:مدل پست و جدول آن در پایگاه دادهبیایید پایگاه داده را با مدل جدید همگام کنیم.برای اعمال مهاجرت‌های موجود، دستور زیر را در ترمینال اجرا کنید:python manage.py migrateخروجی‌ای دریافت خواهید کرد که در پایان آن، این خط دیده می‌شود:Applying blog.0001_initial... OKما اکنون مهاجرت‌های مربوط به برنامه‌هایی را که در INSTALLED_APPS فهرست شده‌اند، اعمال کردیم؛ از جمله برنامه blog. پس از اعمال مهاجرت‌ها، پایگاه داده وضعیت فعلی مدل‌ها را منعکس می‌کند.اگر فایل models.py را ویرایش کنید تا فیلدهای مدل‌های موجود را اضافه، حذف یا تغییر دهید، یا اگر مدل‌های جدیدی اضافه کنید، باید با استفاده از دستور makemigrations یک مهاجرت جدید بسازید. هر مهاجرت به جنگو اجازه می‌دهد تغییرات مدل‌ها را ردیابی کند. سپس باید آن مهاجرت را با دستور migrate اعمال کنید تا پایگاه داده با مدل‌های شما همگام بماند.پست قبلی: (فصل اول - اپیزود ۷ - اضافه کردن ترتیب‌بندی، تنظیم اندیس در پایگاه داده و فعال سازی اپلیکیشن)پست بعدی: (فصل اول - اپیزود ۹ - ایجاد مدیر و پنل مدیریت)</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Mon, 29 Jun 2026 03:04:14 +0330</pubDate>
            </item>
                    <item>
                <title>فصل اول - اپیزود ۷ - ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/%D9%81%D8%B5%D9%84-%D8%A7%D9%88%D9%84-%D8%A7%D9%BE%DB%8C%D8%B2%D9%88%D8%AF-%DB%B7-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-django-5-by-example-ookadpadscs2</link>
                <description>تعیین ترتیب پیش‌فرض برای مرتب‌سازیپست‌های وبلاگ معمولاً به ترتیب زمانی معکوس (از جدید به قدیم) نمایش داده می‌شوند، به طوری که جدیدترین پست‌ها ابتدا مشاهده شوند. ما برای مدل خود، یک ترتیب پیش‌فرض (Default Ordering) تعریف خواهیم کرد. این ترتیب هنگام بازیابی (Retrieving) اشیاء از پایگاه داده اعمال می‌شود، مگر اینکه در کوئری (Query) خاصی، ترتیب متفاوتی تعیین شده باشد.فایل 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)
     created = models.DateTimeField(auto_now_add=True)
     updated = models.DateTimeField(auto_now=True)
     class Meta:
          ordering = [&#039;-publish&#039;]

     def __str__(self):
          return self.titleما یک کلاس Meta در داخل مدل اضافه کرده‌ایم. این کلاس، متاداده‌ها (Metadata) مربوط به مدل را تعریف می‌کند. ما از ویژگی (Attribute) ordering استفاده می‌کنیم تا به جنگو بگوییم که نتایج را بر اساس فیلد publish مرتب کند. این ترتیب مرتب‌سازی، به‌صورت پیش‌فرض برای کوئری‌های دیتابیس اعمال خواهد شد، مگر اینکه ترتیب خاص دیگری در خودِ کوئری تعیین شده باشد. ما با استفاده از یک خط تیره (-) قبل از نام فیلد (-publish)، ترتیب نزولی (Descending) را مشخص می‌کنیم. در نتیجه، پست‌ها به‌صورت پیش‌فرض با ترتیب زمانی معکوس (از جدید به قدیم) بازگردانده خواهند شد.افزودن ایندکس (Index) به پایگاه دادهبیایید یک ایندکس پایگاه داده برای فیلد publish تعریف کنیم. این کار باعث بهبود عملکرد (Performance) در هنگام فیلتر کردن کوئری‌ها یا مرتب‌سازی نتایج بر اساس این فیلد می‌شود. باتوجه به اینکه نتایج را به صورت پیشفرض بر اساس فیلد publish مرتب می‌کنیم درنتیجه کوئری‌های خیلی زیادی از این ایندکس استفاده میکنند و باعث افزایش سرعت کوئری می‌شود.فایل 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)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = [&#039;-publish&#039;]
        
        indexes = [
            models.Index(fields=[&#039;-publish&#039;]),
        ]

    def __str__(self):
        return self.titleما گزینه indexes را به کلاس Meta مدل اضافه کرده‌ایم. این گزینه به شما اجازه می‌دهد ایندکس‌های پایگاه داده را برای مدل خود تعریف کنید؛ این ایندکس‌ها می‌توانند شامل یک یا چند فیلد، با ترتیب صعودی یا نزولی، و یا حتی عبارات عملکردی (Functional Expressions) و توابع دیتابیس باشند. ما یک ایندکس برای فیلد publish اضافه کردیم. با استفاده از یک خط تیره قبل از نام فیلد، ایندکس را مشخصاً با ترتیب نزولی(ِDecsending) تعریف کرده‌ایم. فرآیند ایجاد این ایندکس، در عملیات مهاجرت پایگاه داده (Database Migrations) که در مراحل بعد برای مدل‌های وبلاگ خود ایجاد می‌کنیم، گنجانده خواهد شد.نکته مهم: قابلیت تعیین ترتیب (Ordering) در ایندکس، در MySQL پشتیبانی نمی‌شود. اگر از MySQL به عنوان پایگاه داده استفاده می‌کنید، یک ایندکس نزولی در واقع به صورت یک ایندکس معمولی (صعودی) ساخته خواهد شد.فعال‌سازی اپلیکیشن blogاکنون وقت آن رسیده که اپلیکیشن خود را جهت فعال‌سازی در پروژه‌مان به سیستم جنگو معرفی شود.این کار باعث می‌شود جنگو پیگیر تغییرات اپلیکیشن باشد و همچنین بتواند جداول پایگاه داده را بر اساس مدل‌ها بسازد.برای این کار باید فایل settings.py را ویرایش کنید و آیتم &quot;blog.apps.BlogConfig&quot; را به لیستی تحت عنوان INSTALLED_APPS اضافه کنید: مانند نمونه کد زیر:INSTALLED_APPS in settings.pyکلاس BlogConfig تنظیمات مربوط به این اپلیکیشن را مشخص می‌کند. با این کار جنگو متوجه می‌شود که این اپلیکیشن در این پروژه فعال شده است و از این پس می‌تواند مدل‌های آن را بارگزاری کند.اضافه کردن یک فیلد وضعیت انتشاریکی از قابلیت‌های رایج در وبلاگ‌ها این است که نوشته‌ها تا زمانی که آماده انتشار شوند، به صورت پیش‌نویس (Draft) ذخیره شوند. ما یک فیلد status به مدل خود اضافه می‌کنیم که به ما اجازه می‌دهد وضعیت پست‌های وبلاگ را مدیریت کنیم. برای پست‌ها از دو وضعیت Draft و Published استفاده خواهیم کرد.فایل models.py در اپلیکیشن blog را ویرایش کنید تا به شکل زیر درآید:status field in Post modelما کلاس شمارشی (Enumeration) به نام Status را با ارث‌بری از models.TextChoices تعریف کرده‌ایم. گزینه‌های موجود برای وضعیت پست عبارت‌اند از:DRAFTPUBLISHEDمقادیر آن‌ها به ترتیب:DFPBو نام‌های نمایشی آن‌ها به ترتیب:DraftPublishedجنگو نوع‌هایی از enumeration ارائه می‌دهد که می‌توانید از آن‌ها ارث‌بری کنید تا گزینه‌ها (choices) را به شکل ساده‌تری تعریف کنید. این نوع‌ها بر پایه شیء enum در کتابخانه استاندارد پایتون ساخته شده‌اند.برای مطالعه بیشتر درباره enum می‌توانید به این لینک مراجعه کنید:https://docs.python.org/3/library/enum.htmlنوع‌های enumeration در جنگو چند تغییر نسبت به enum استاندارد دارند. درباره این تفاوت‌ها می‌توانید در مستندات جنگو مطالعه کنید:https://docs.djangoproject.com/en/5.0/ref/models/fields/#enumeration-typesما می‌توانیم از ویژگی‌های زیر استفاده کنیم:Post.Status.choicesبرای دریافت همه گزینه‌های قابل انتخابPost.Status.namesبرای دریافت نام گزینه‌هاPost.Status.labelsبرای دریافت نام‌های نمایشیPost.Status.valuesبرای دریافت مقادیر واقعی گزینه‌هااکنون ما یک فیلد جدید به نام status به مدل اضافه کرده‌ایم که از نوع CharField است. این فیلد شامل پارامتر choices است که مقدار آن را به گزینه‌های تعریف‌شده در Status محدود می‌کند.همچنین با استفاده از پارامتر default یک مقدار پیش‌فرض برای این فیلد تعیین کرده‌ایم. در اینجا مقدار پیش‌فرض DRAFT در نظر گرفته شده است.یک روش خوب در طراحی مدل‌ها این است که choices را داخل همان کلاس مدل تعریف کنید و از enumeration types استفاده کنید. این کار باعث می‌شود بتوانید در هر جای کد به راحتی به label، value یا name گزینه‌ها دسترسی داشته باشید.برای مثال می‌توانید مدل Post را import کنید و در هر جای کد از مقدار زیر به عنوان مرجع وضعیت پیش‌نویس استفاده کنید:Post.Status.DRAFTبیایید ببینیم چگونه می‌توان با status choices کار کرد.دستور زیر را در ترمینال اجرا کنید تا Python shell باز شود:python manage.py shellسپس خطوط زیر را وارد کنید:&gt;&gt;&gt; from blog.models import Post
&gt;&gt;&gt; Post.Status.choicesدر این حالت، گزینه‌های enum به صورت جفت‌های مقدار و نام نمایشی (value-label pairs) نمایش داده می‌شوند، مانند:[(&#039;DF&#039;, &#039;Draft&#039;), (&#039;PB&#039;, &#039;Published&#039;)]خط زیر را وارد کنید:Post.Status.labelsدر این صورت، نام‌های خوانا برای انسان (human-readable names) از اعضای enum را دریافت می‌کنید:[&#039;Draft&#039;, &#039;Published&#039;]خط زیر را وارد کنید:Post.Status.valuesدر این حالت، مقادیر واقعی اعضای enum را دریافت خواهید کرد. این‌ها همان مقادیری هستند که در پایگاه داده برای فیلد status ذخیره می‌شوند:[&#039;DF&#039;, &#039;PB&#039;]خط زیر را وارد کنید:Post.Status.namesدر نتیجه، نام گزینه‌ها (names) را دریافت می‌کنید:[&#039;DRAFT&#039;, &#039;PUBLISHED&#039;]همچنین می‌توانید به یک عضو خاص از enumeration به این شکل دسترسی داشته باشید:pythonPost.Status.PUBLISHEDو می‌توانید به ویژگی‌های آن نیز دسترسی پیدا کنید:Post.Status.PUBLISHED.namePost.Status.PUBLISHED.valueاین ویژگی‌ها به ترتیب نام عضو enum و مقدار واقعی آن را برمی‌گردانند.پست قبلی: (فصل اول - اپیزود ۶ - ایجاد اپ بلاگ و توضیح موارد آن)پست بعدی: (فصل اول - اپیزود ۸ - رابطه یک به چند کاربر نویسنده به پست‌ها و مایگرشن به دیتابیس)کم کم داره جذاب میشه کتاب و پیشنهاد میکنم شمایی که تا اینجا همراه با من بودید، ادامه کتاب رو از دست ندید👍😉</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Sun, 28 Jun 2026 01:26:05 +0330</pubDate>
            </item>
                    <item>
                <title>فصل اول - اپیزود ۶ - ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/%D9%81%D8%B5%D9%84-%D8%A7%D9%88%D9%84-%D8%A7%D9%BE%DB%8C%D8%B2%D9%88%D8%AF-%DB%B6-%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF-%D8%A7%D9%BE-%D8%A8%D9%84%D8%A7%DA%AF-%D9%88-%D9%85%D8%AF%D9%84-%D9%87%D8%A7%DB%8C-%D8%AF%D8%A7%D8%AF%D9%87-dm1bxp1bgdd0</link>
                <description>فصل اول - اپیزود ۶ ترجمه کتاب 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 initadmin.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)پست بعدی: (فصل اول - اپیزود ۷ - اضافه کردن ترتیب‌بندی، تنظیم اندیس در پایگاه داده و فعال سازی اپلیکیشن)</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Sat, 27 Jun 2026 00:51:14 +0330</pubDate>
            </item>
                    <item>
                <title>فصل اول - اپیزود ۵ - ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/%D9%81%D8%B5%D9%84-%D8%A7%D9%88%D9%84-%D8%A7%D9%BE%DB%8C%D8%B2%D9%88%D8%AF-%DB%B5-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-django-5-by-example-django-settings-vevejrzvgngm</link>
                <description>توی این اپیزود سعی داریم تنظیمات پروژه جنگو را یاد بگیریم و کمی بیشتر درمورد فایل settings.py و موارد داخلش بدونیم.ترجمه کتاب Django 5 By Example - فصل اول - اپیزود ۵ - یادگیری تنظیمات جنگو و فایل settings.pyبیایید فایل settings.py را باز کنیم و نگاهی به تنظیمات پروژه بیندازیم.جنگو تعدادی تنظیمات را به‌صورت پیش‌فرض در این فایل قرار می‌دهد، اما این‌ها فقط بخشی از تمام تنظیمات موجود در Django هستند.شما می‌توانید همه‌ی تنظیمات و مقادیر پیش‌فرض جنگو را در این آدرس ببینید:https://docs.djangoproject.com/en/5.0/ref/settings/بیایید برخی از تنظیمات مهم پروژه را بررسی کنیم:DEBUG: حالت خطایابی - یک مقدار بولین (True / False) است که حالت دیباگ پروژه را فعال یا غیرفعال می‌کند.اگر مقدار آن True باشد، زمانی که در برنامه خطای مدیریت‌نشده‌ای (uncaught exception) رخ دهد، جنگو صفحه‌ی خطای کامل و جزئیات فنی را نمایش می‌دهد.وقتی پروژه را به محیط production منتقل می‌کنید، باید مقدار آن را False قرار دهید. هرگز وبسایتی را با حالت DEBUG = True در محیط production منتشر نکنید، چون ممکن است اطلاعات حساس پروژه نمایش داده شود.ALLOWED_HOSTS: تا زمانی که حالت خطایابی فعال باشد یا تست‌ها درحال اجرا باشند، این تنظیم اعمال نمی‌شود.اما وقتی پروژه را به production منتقل کنید و DEBUG=False شود، باید دامنه یا هاست سایت خود را در این لیست قرار دهید تا جنگو اجازه دهد درخواست‌ها از آن دامنه مجاز به سرویس‌دهی شوند.INSTALLED_APPS: کی از تنظیماتی است که تقریباً در همه پروژه‌ها باید آن را ویرایش کنید.این تنظیم مشخص می‌کند که کدام اپلیکیشن‌ها در سایت فعال هستند.به‌صورت پیش‌فرض Django این اپلیکیشن‌ها را اضافه می‌کند:django.contrib.admin - پنل مدیریت وبسایتdjango.contrib.auth - فریم‌ورک احراز هویت (authentication)django.contrib.contenttypes - سیستم مدیریت انواع محتوا در جنگوdjango.contrib.sessions - سیستم مدیریت سشن هاdjango.contrib.messages - سیستم ارسال پیام‌ها بین درخواست‌هاdjango.contrib.staticfiles - سیستمی برای مدیریت فایل‌های استاتیکMIDDLEWARE: لیستی از میان‌افزارها است که هنگام پردازش درخواست‌ها اجرا می‌شوند.ROOT_URLCONF: ماژول پایتونی را مشخص می‌کند که URLهای اصلی پروژه در آن تعریف شده‌اند.DATABASES: یک دیکشنری شامل تنظیمات تمام پایگاه‌های داده‌ی پروژه است.همیشه باید حداقل یک دیتابیس با نام default وجود داشته باشد.تنظیمات پیش‌فرض جنگو استفاده از SQLite3 است.LANGUAGE_CODE: زبان پیشفرض پروژه جنگو را مشخص میکند.USE_TZ: مشخص می‌کند که آیا پشتیبانی از timezone فعال باشد یا خیر.جنگو به‌صورت پیش‌فرض از دیتابیس‌های وابسته به timezone (timezone‑aware) پشتیبانی می‌کند.این متغیر زمانی که پروژه را به وسیله دستور startproject ایجاد میکنید مقدار True قرار میگیرد.اگر در حال حاضر چیز زیادی از آنچه در این پست می‌بینید متوجه نمی‌شوید، نگران نباشید.در فصل‌های بعدی بیشتر با تنظیمات مختلف جنگو آشنا خواهید شد.پست قبلی: (فصل اول - اپیزود ۴ - ایجاد اولین پروژه جنگو)پست بعدی: (فصل اول - اپیزود ۶ - ایجاد اپ بلاگ و توضیح موارد آن )</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Sun, 17 May 2026 01:10:30 +0330</pubDate>
            </item>
                    <item>
                <title>فصل اول - اپیزود ۴ - ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/%D9%81%D8%B5%D9%84-%D8%A7%D9%88%D9%84-%D8%A7%D9%BE%DB%8C%D8%B2%D9%88%D8%AF-%DB%B4-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-django-5-by-example-django-architecture-django-migrations-rzvb17f2gthw</link>
                <description>ترجمه کتاب Django 5 By Example - فصل اول - اپیزود ۴ - ساخت اولین پروژه در جنگوایجاد اولین پروژه جنگواولین پروژه‌ای که با جنگو می‌سازید یک اپلیکیشن وبلاگ خواهد بود. این پروژه یک مقدمه‌ی خوب برای آشنایی با قابلیت‌ها و امکانات جنگو فراهم می‌کند.وبلاگ‌نویسی نقطه‌ی شروع بسیار مناسبی برای ساخت یک پروژه‌ی کامل با جنگو است، چون طیف گسترده‌ای از قابلیت‌ها را در بر می‌گیرد؛ از مدیریت ساده‌ی محتوا گرفته تا امکانات پیشرفته‌تری مثل کامنت‌گذاری، اشتراک‌گذاری پست‌ها، جستجو و پیشنهاد پست‌های مرتبط به کاربران.پروژه‌ی وبلاگ در سه فصل اولِ این کتاب بررسی می‌شود.در فصل فعلی اقدامات زیر را انجام خواهیم داد:ابتدا یک پروژه جنگو ایجاد می‌کنیم و یک اپلیکیشن برای وبلاگ می‌سازیم.سپس مدل‌های داده (Data Models) را تعریف کرده و آن‌ها را با پایگاه داده هماهنگ می‌کنیم.در نهایت Viewها، Templateها و URLها را میسازیم و همچنین یک پنل مدیریت برای مدیریت محتوای وبلاگ ایجاد می‌کنیم.شکل زیر نمای کلی اپلیکیشن وبلاگی که قرار است بسازید را نشان میدهد:اپلیکیشن وبلاگ شامل یک صفحه لیست تمامی پست‌ها خواهد بود که در آن اطلاعاتی مانند عنوان پست، تاریخ انتشار، نویسنده، خلاصه‌ای از متن پست (excerpt) و یک لینک برای خواندن کامل پست نمایش داده می‌شود. صفحه‌ی لیست پست‌ها با استفاده از view ای به نام post_list پیاده‌سازی خواهد شد. در این فصل یاد می‌گیرید که چگونه در جنگو یک View ایجاد کنید.وقتی کاربران روی لینک یک پست در صفحه‌ی لیست همه پست‌ها کلیک کنند، به صفحه‌ی نمایش جزئیات همان پست (detail view) هدایت می‌شوند. در این صفحه عنوان پست، تاریخ انتشار، نویسنده و متن کامل پست نمایش داده خواهد شد.اکنون بیایید یک پروژه‌ی جنگو برای وبلاگمان ایجاد کنیم. فریمورک جنگو دستوری فراهم کرده که با استفاده از آن می‌توانید ساختار اولیه‌ی فایل‌های یک پروژه را به‌صورت خودکار ایجاد کنید.دستور زیر را در خط فرمان سیستم خود اجرا کنید:django-admin startproject mysiteاین دستور یک پروژه جنگو به نام mysite ایجاد میکند.نکته: از نام‌گذاری پروژه‌ها مشابه با نام ماژول‌های داخلی پایتون یا جنگو خودداری کنید، زیرا ممکن است باعث تداخل و خطا شود.ساختار پروژه:بیایید نگاهی به ساختار پروژه ایجاد شده بیاندازیمmysite/
   manage.py
   mysite/
     ــinitــ.py
     asgi.py
     settings.py
     urls.py
     wsgi.pyپوشه‌ی بیرونی /mysite به‌عنوان جعبه اصلی پروژه عمل می‌کند و شامل فایل‌های زیر است:manage.py: یک ابزار خط فرمان برای تعامل با پروژه است. معمولاً نیازی نیست این فایل را ویرایش کنید./mysite: این پوشه در واقع پکیج پایتون پروژه است و شامل فایل‌های زیر می‌شود:init___.py___: ک فایل خالی است که به پایتون می‌گوید پوشه‌ی mysite باید به‌عنوان یک ماژول پایتون در نظر گرفته شود.asgi.py: تنظیمات لازم برای اجرای پروژه به‌عنوان یک اپلیکیشن ASGI با وب‌سرورهایی که از ASGI پشتیبانی می‌کنند.ASGI استاندارد جدید پایتون برای وب‌سرورهای asynchronous و اپلیکیشن‌های وب محسوب می‌شود.settings.py: شامل تنظیمات و پیکربندی پروژه است و تنظیمات پیش‌فرض اولیه‌ی جنگو در آن قرار دارد.urls.py: جایی است که الگوهای URL پروژه تعریف می‌شوند. هر URL در اینجا به یک view متصل (map) می‌شود.wsgi.py: تنظیمات لازم برای اجرای پروژه به‌عنوان یک اپلیکیشن WSGI با وب‌سرورهایی که از WSGI پشتیبانی می‌کنند.اعمال مایگریشن‌های اولیه‌ی پایگاه دادهاپلیکیشن‌های جنگو برای ذخیره‌ی داده‌ها به پایگاه داده نیاز دارند. فایل settings.py شامل تنظیمات مربوط به پایگاه داده‌ی پروژه است که در متغیر DATABASES تعریف می‌شود.تنظیمات پیش‌فرض جنگو استفاده از پایگاه داده SQLite3 است.SQLite همراه با Python 3 ارائه می‌شود و می‌توان از آن در هر برنامه‌ی پایتونی استفاده کرد.SQLite یک پایگاه داده‌ی سبک (lightweight) است که برای محیط توسعه (development) در پروژه های جنگو بسیار مناسب است.اما اگر قصد دارید اپلیکیشن خود را در محیط نهایی محصول (production) منتشر کنید، بهتر است از یک پایگاه داده‌ی کامل‌تر مانند موارد زیر استفاده کنید:PostgreSQLMySQLOracleاطلاعات بیشتر درباره‌ی راه‌اندازی پایگاه داده در جنگو را می‌توانید در مستندات مربوطه پیدا کنید.https://docs.djangoproject.com/en/5.0/topics/install/#database-installationهمچنین فایل settings.py شامل متغیری از جنس لیست به نام INSTALLED_APPS است که تعدادی از اپلیکیشن‌های رایج جنگو را در بر دارد و به‌صورت پیش‌فرض به پروژه‌ی شما اضافه می‌شوند.بعداً در بخش تنظیمات پروژه این اپلیکیشن‌ها را به‌طور کامل بررسی خواهیم کرد.اپلیکیشن‌های پیشفرض موجود در پروژه جنگو شامل مدل‌های داده (Data Models) هستند که به جداول دیتابیس تطبیق داده می‌شوند.شما مدل‌های خودتان را در بخش &quot;ایجاد مدل های وبلاگ&quot; ایجاد خواهید کرد. اما برای کامل شدن راه‌اندازی پروژه، ابتدا باید جدول‌های مربوط به مدل‌های اپلیکیشن‌های پیش‌فرض جنگو که در تنظیم INSTALLED_APPS قرار دارند، در پایگاه داده ایجاد شوند.جنگو دارای سیستمی به نام مهاجرت | migration است که به شما کمک می‌کند تغییرات مربوط به ساختار پایگاه داده را مدیریت کنید.خط فرمان را باز کنید و دستورات زیر را اجرا کنید: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) هستند که توسط جنگو اعمال می‌شوند.با اجرای مهاجرت‌های اولیه، جدول‌های مربوط به اپلیکیشن‌هایی که در تنظیمات INSTALLED_APPS قرار دارند در دیتابیس ایجاد می‌شوند.در بخش Creating and applying migrations این فصل، بیشتر درباره دستور مدیریتیmigrateیاد خواهید گرفت.اجرای سرور توسعهجنگو به‌صورت پیش‌فرض یک وب‌سرور سبک داخلی دارد که به شما اجازه می‌دهد بدون نیاز به تنظیمات پیچیده‌ی سرورهای production، خیلی سریع کدتان را اجرا کنید.وقتی سرور توسعه‌ی جنگو را اجرا می‌کنید، این سرور به‌طور مداوم تغییرات کدنویسی را بررسی می‌کند. اگر تغییری در کد ایجاد شود، سرور به‌صورت خودکار باز-اجرا (reload) می‌شود و نیازی نیست بعد از هر تغییر، آن را بطور دستی ریستارت کنید.با این حال، در بعضی موارد مثل اضافه کردن فایل جدید به پروژه، ممکن است سرور متوجه تغییر نشود؛ در این حالت باید سرور را به‌صورت دستی ریستارت کنید.به وسیله دستور زیر در خط فرمان، سرور توسعه شما اجرا خواهد شد:python manage.py runserverهمچنین باید خروجی مشابه زیر ببینید:Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
January 01, 2024 - 10:00:00
Django version 5.0, using settings &#039;mysite.settings&#039;
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.اکنون در مرورگر خود به آدرس لوکال هاست با پورت ۸۰۰۰ بروید.http://127.0.0.1:8000/یاhttp://localhost:8000/درنهایت صفحه ابتدایی جنگو را میبینید که نشان از اجرای موفق‌آمیز پروژه است.(مانند تصویر زیر)اسکرین‌شاتی که در بالا دیدید نشان می‌دهد که جنگو در حال اجرا است. اگر به کنسول (console) خود نگاه کنید، درخواست GET که توسط مرورگر شما ارسال شده است را خواهید دید.(چیزی شبیه به زیر)[01/Jan/2024 10:00:15] &quot;GET / HTTP/1.1&quot; 200 16351هر درخواست HTTP توسط سرور توسعه‌ی جنگو در کنسول ثبت (log) می‌شود. همچنین هر خطایی که هنگام اجرای سرور توسعه رخ دهد نیز در کنسول نمایش داده می‌شود.شما می‌توانید سرور توسعه‌ی جنگو را روی یک host و پورت دلخواه اجرا کنید یا به جنگو بگویید یک فایل تنظیمات (settings) خاص را بارگذاری کند، به شکل زیر:python manage.py runserver 127.0.0.1:8001 --settings=mysite.settingsنکته: زمانی که با محیط‌های مختلفی سر و کار دارید که نیاز به تنظیمات متفاوتی دارند، می‌توانید برای هر محیط یک فایل تنظیمات (settings file) جداگانه ایجاد کنید.(مانند محیط‌های توسعه، خطایابی، پروداکشن و ...)این سرور (سرور توسعه‌ی جنگو) فقط برای محیط توسعه (development) در نظر گرفته شده و برای استفاده در محیط واقعی (production) مناسب نیست.برای استقرار(deploy) جنگو در محیط production، باید آن را به‌عنوان یک برنامه WSGI با استفاده از یک وب‌سرور مانند Apache، Gunicorn یا uWSGI، یا به‌عنوان یک برنامه ASGI با استفاده از سروری مثل Daphne یا Uvicorn اجرا کنید.اطلاعات بیشتر در مورد چگونگی راه‌اندازی جنگو با وب‌سرورهای مختلف را می‌توانید در آدرس زیر پیدا کنید:https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/همچنین، در فصل ۱۷ با عنوان راه‌اندازی-نهایی|Going Live، نحوه‌ی آماده‌سازی محیط production برای پروژه‌های جنگوی شما را توضیح می‌دهد.مطالعه ادامه ترجمه کتابپست قبلی: (فصل اول - اپیزود ۳ - مرور کلی بر جنگو و معماری آن )پست بعدی: (فصل اول - اپیزود ۵ - تنظیمات پروژه و فایل settings.py)</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Sat, 16 May 2026 17:02:46 +0330</pubDate>
            </item>
                    <item>
                <title>فصل اول - اپیزود ۳ - ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/%D9%81%D8%B5%D9%84-%D8%A7%D9%88%D9%84-%D8%A7%D9%BE%DB%8C%D8%B2%D9%88%D8%AF-%DB%B3-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-django-5-by-example-new-features-in-django-kshnrxqsjcoq-kshnrxqsjcoq</link>
                <description>توی این اپیزود مرور کوتاهی داریم بر جنگو و معماری MVT و همچنین ویژگی های جدید جنگو ۵ رو بررسی میکنیم.مرور کلی بر جنگوجنگو یک فریم‌ورک است که از مجموعه‌ای از مؤلفه‌ها تشکیل شده و مشکلات رایج توسعه‌ی وب را حل می‌کند.مؤلفه‌های جنگو به‌صورت loosely coupled (یعنی با اتصال ضعیف به یکدیگر) طراحی شده‌اند، به این معنا که هر کدام می‌توانند به‌طور مستقل مدیریت شوند. این ویژگی کمک می‌کند وظایف لایه‌های مختلف فریم‌ورک از هم جدا باشند؛ به‌عنوان مثال، لایه‌ی پایگاه داده هیچ اطلاعی از نحوه‌ی نمایش داده‌ها ندارد، سیستم قالب‌بندی (template system) هیچ شناختی از درخواست‌های وب ندارد، و به همین ترتیب سایر بخش‌ها نیز مستقل هستند.جنگو با پیروی از اصل DRY (don’t repeat yourself / خودت را تکرار نکن)، حداکثر قابلیت استفاده مجدد از کد را فراهم می‌کند.جنگو به توسعه سریع برنامه‌ها کمک می‌کند و با استفاده از قابلیت‌های پویای پایتون، مانند introspection، این امکان را می‌دهد که با کدنویسی کمتر کارهای بیشتری انجام دهید.همنچنین شما میتوانید درمورد فلسفه های جنگو بخوانید.https://docs.djangoproject.com/en/5.0/misc/design-philosophies/نکته: دقت کنید که لینک بالا، در نسخهٔ فعلی جنگو هشدار می‌دهد که این نسخه از جنگو دیگر پشتیبانی نمی‌شود و بهتر است به نسخهٔ جدیدتر ارتقا داده شود. اما چون در متن کتاب بود و هدف ترجمه این کتاب هست حذفش نکردم.اجزای اصلی فریم‌ورک جنگوجنگو از الگوی MTV (Model‑Template‑View) پیروی می‌کند. این الگو تا حدی شبیه الگوی شناخته‌شدهٔ MVC (Model‑View‑Controller) است؛ با این تفاوت که در جنگو Template نقش View را دارد و خود فریم‌ورک نقش Controller را ایفا می‌کند.در الگوی MTV جنگو، مسئولیت‌ها به شکل زیر تقسیم می‌شوند:Model: ساختار منطقی داده‌ها را تعریف می‌کند و به‌عنوان واسطهٔ مدیریت داده‌ها بین پایگاه داده و View عمل می‌کند.Template: لایهٔ نمایش (presentation layer) است. جنگو از یک سیستم قالب مبتنی بر متن ساده استفاده می‌کند که هر چیزی را که در مرورگر نمایش داده می‌شود مدیریت می‌کند.View: از طریق Model با پایگاه داده ارتباط برقرار می‌کند و داده‌ها را برای نمایش به Template ارسال می‌کند.خود فریم‌ورک نقش Controller را دارد. فریم‌ورک بر اساس تنظیمات URL در جنگو، درخواست را به View مناسب ارسال می‌کند.هنگام توسعهٔ هر پروژهٔ جنگو، همیشه با مدل‌ها، ویوها، تمپلیت‌ها و URLها کار خواهید کرد. در این فصل یاد می‌گیرید که این بخش‌ها چگونه در کنار یکدیگر قرار می‌گیرند.معماری جنگو چگونه کار میکندشکل زیر نشان می‌دهد که جنگو چگونه درخواست‌ها را پردازش می‌کند و چرخهٔ درخواست/پاسخ (request/response cycle) چگونه با استفاده از اجزای اصلی جنگو—یعنی URLها، ویوها، مدل‌ها و تمپلیت‌ها—مدیریت می‌شود.معماری جنگو - چرخه درخواست تا پاسخ در جنگوفرآیند مدیریت درخواست‌های HTTP و تولید پاسخ در جنگو به این صورت انجام می‌شود:یک مرورگر وب با استفاده از یک URL صفحه‌ای را درخواست می‌کند و وب‌سرور این درخواست HTTP را به جنگو ارسال می‌کند.جنگو الگوهای URL پیکربندی‌شده را بررسی می‌کند و وقتی به اولین الگویی برسد که با URL درخواستی مطابقت دارد، متوقف می‌شود.جنگو View مربوط به آن الگوی URL را اجرا می‌کند.View در صورت نیاز از مدل‌های داده (Models) برای دریافت اطلاعات از پایگاه داده استفاده می‌کند.مدل‌های داده ساختار داده‌ها و رفتار آن‌ها را تعریف می‌کنند و برای پرس‌وجو(Query) از پایگاه داده به کار می‌روند.View یک Template (معمولاً HTML) را برای نمایش داده‌ها پردازش (Render) می‌کند و آن را در قالب یک پاسخ HTTP برمی‌گرداند.در پایان این فصل و در بخش چرخهٔ درخواست/پاسخ (The request/response cycle) دوباره به این فرآیند بازخواهیم گشت.همچنین جنگو در فرایند درخواست/پاسخ نقاط اتصالی دارد که میان‌افزار(Middleware) نام دارد. اما برای ساده بودن نمودار بالا، بطور موقت حذف شده و در فصول بعدی بطور کامل به آن میپردازیم.(به فصل ۱۷ مراجعه کنید)تا اینجا عناصر پایه‌ای جنگو و نحوه پردازش درخواست‌ها توسط آن را بررسی کرده‌ایم. اکنون بیایید ویژگی‌های جدید معرفی‌شده در Django 5 را بررسی کنیم.ویژگی‌های جدید در جنگو ۵جنگو ۵ چندین قابلیت مهم جدید معرفی می‌کند که در مثال‌های این کتاب از آن‌ها استفاده خواهید کرد.این نسخه همچنین برخی قابلیت‌ها را منسوخ (deprecated) اعلام کرده و بعضی از قابلیت‌هایی را که قبلاً منسوخ شده بودند، به‌طور کامل حذف کرده است.ویژگی‌های جدید و مهم Django 5.0:فیلترهای Facet در پنل مدیریت:اکنون می‌توان فیلترهای Facet را به بخش مدیریت جنگو اضافه کرد. وقتی این قابلیت فعال باشد، برای فیلترهایی که در لیست اشیای Admin اعمال شده‌اند، تعداد نتایج هر فیلتر نیز نمایش داده می‌شود. این قابلیت در بخش Added facet counts to filters همین فصل توضیح داده شده است.ساده‌تر شدن قالب‌های رندر فیلدهای فرم:رندر کردن فیلدهای فرم ساده‌تر شده است. اکنون می‌توان گروه‌هایی از فیلدها (field groups) را تعریف کرد که هرکدام قالب (template) مخصوص خود را دارند. این کار باعث می‌شود اجزای مرتبط با یک فیلد فرم مانند label، widget، متن راهنما (help text) و خطاها راحت‌تر و منظم‌تر نمایش داده شوند. نمونه‌ای از استفاده از field groups در بخش Creating templates for the comment form در فصل ۲ کتاب آورده شده است.مقادیر پیش‌فرض محاسبه‌شده در دیتابیس:جنگو اکنون از مقادیر پیش‌فرضی پشتیبانی می‌کند که توسط خود دیتابیس محاسبه می‌شوند. نمونه‌ای از این قابلیت در بخش Adding datetime fields همین فصل ارائه شده است.فیلدهای مدل که توسط دیتابیس تولید می‌شوند:یک نوع جدید از فیلدها معرفی شده است که به شما اجازه می‌دهد ستون‌هایی در دیتابیس داشته باشید که مقدارشان به‌صورت خودکار توسط دیتابیس تولید می‌شود. مقدار این فیلدها با استفاده از یک عبارت(expression) تعیین می‌شود و هر بار که مدل تغییر کند، مقدار آن بر اساس همان عبارت دوباره محاسبه می‌شود. این کار با استفاده از دستورات SQL به نام GENERATED ALWAYS انجام می‌شود.گزینه‌های بیشتر برای تعریف choices در فیلدهای مدل:در فیلدهایی که از choices پشتیبانی می‌کنند، دیگر لازم نیست برای دسترسی به enumها از ویژگی choices. استفاده کنید. اکنون می‌توان به‌جای یک iterable، مستقیماً از mapping یا callable استفاده کرد تا enumها گسترش داده شوند. مثال این تغییر در بخش Adding a status field همین فصل آمده است.بهبود پشتیبانی از برنامه‌نویسی ناهمزمان در جنگو ۵جنگو ۵ همچنین چند بهبود در زمینه پشتیبانی از پردازش ناهمزمان (asynchronous) ارائه کرده است.پشتیبانی از ASGI (Asynchronous Server Gateway Interface) اولین بار در Django 3 معرفی شد و در Django 4.1 بهبود پیدا کرد؛ در آن نسخه قابلیت‌هایی مثل هندلرهای async برای viewهای مبتنی بر کلاس (Class-Based Views) و همچنین رابط ORM به‌صورت asynchronous اضافه شدند.در Django 5 نیز پیشرفت‌های جدیدی اضافه شده است:اضافه شدن توابع async به سیستم احراز هویت جنگو (authentication framework)پشتیبانی از ارسال سیگنال‌ها به‌صورت asynchronousاضافه شدن پشتیبانی async به چندین decorator داخلی جنگوبه‌طور خلاصه، جنگو در هر نسخه بیشتر به سمت پشتیبانی کامل از معماری async پیش می‌رود تا بتواند بهتر با WebSocketها، درخواست‌های همزمان زیاد، و سیستم‌های real‑time کار کند.نکته: جنگو ۵.۰ دیگر از پایتون در نسخه های 3.8 و 3.9 پشتیبانی نمی‌کند.لیست تمامی تغییرات و ویژگی‌های جنگو ۵.۰ را میتوانید از این لینک بخوانید:https://docs.djangoproject.com/en/5.0/releases/5.0از آنجا که انتشار Django بر اساس زمان‌بندی انجام می‌شود در نسخه ۵ تغییرات اساسی و بزرگی وجود ندارد. به همین دلیل ارتقای پروژه‌هایی که با Django 4 ساخته شده‌اند به Django 5.0 معمولاً ساده و مستقیم است.اگر بخواهید یک پروژه‌ی موجود Django را سریع به نسخه 5.0 ارتقا دهید، می‌توانید از ابزار django-upgrade استفاده کنید. این پکیج فایل‌های پروژه‌ی شما را بررسی کرده و با اعمال مجموعه‌ای از fixerها (اصلاحات خودکار کد) آن‌ها را به نسخه‌ی هدف بازنویسی می‌کند.طریقه استفاده از django-upgrade را می‌توانید در صفحه مستندات رسمی مطالعه کنید:https://github.com/adamchainz/django-upgradeابزار django-upgrade با الهام از پکیجی به نام pyupgrade ساخته شده است.با استفاده از pyupgrade می‌توانید به‌صورت خودکار ساختارهای قدیمی کد پایتون را به سینتکس نسخه‌های جدیدتر پایتون ارتقا دهید.برای کسب اطلاعات بیشتر درمورد pyupgrade به صفحه مستندات با لینک زیر مراجعه کنید:https://github.com/asottile/pyupgradeمطالعه ادامه ترجمه کتابپست قبلی: (فصل اول - اپیزود ۲ - نصب جنگو)پست بعدی: (فصل اول - اپیزود ۴ - ایجاد اولین پروژه جنگویی)</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Fri, 15 May 2026 17:40:18 +0330</pubDate>
            </item>
                    <item>
                <title>فصل اول - اپیزود ۲ - ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/httpsvirgooliorezarezaeedev%D9%81%D8%B5%D9%84-%D8%A7%D9%88%D9%84-%D8%A7%D9%BE%DB%8C%D8%B2%D9%88%D8%AF-%DB%B2-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-django-5-by-example-installing-django-c2kjc5irkpeq-c2kjc5irkpeq</link>
                <description>ترجمه کتاب Django 5 By Example - نصب جنگونصب جنگواگر قبلا جنگو نسخه ۵ را در سیستمتان نصب کرده اید میتوانید مستقیما به اپیزود بعدی(معرفی جنگو ۵ و ویژگی های جدید جنگو) بروید و نیازی نیست این اپیزود را مطالعه کنید.جنگو به‌صورت یک ماژول پایتون ارائه می‌شود، بنابراین می‌توان آن را در هر محیط پایتونی نصب کرد. اگر هنوز جنگو را نصب نکرده‌اید، ادامه‌ی مطلب یک راهنمای نصب سریع برای شماست.نصب جنگو به وسیله pipسیستم مدیریت نسخه pip بهترین روش نصب جنگو است. پایتون 3.12 به بعد بطور پیشفرض pip را نصب میکند اما شما میتوانید مستندات نصب pip را از وبسایت رسمی آن بخوانید:https://pip.pypa.io/en/stable/installation/به وسیله اجرای کد زیر در خط فرمان میتوانید جنگو را نصب کنید:python -m pip install Django~=5.0.4این دستور آخرین نسخه جنگو ۵ را در پوشه site-packages در پوشه مربوط به محیط مجازی پایتون شما نصب میکند.اکنون بررسی میکنیم که آیا جنگو به درستی نصب شده است یا خیر! کد زیر را در خط فرمان اجرا کنید.python -m django --versionاگر خروجی آن با ۵.۰ شروع شده باشد، جنگو به درستی نصب شده است و قابل استفاده میباشد. اما اگر پیغامی شبیه به No module named Django مشاهده کردید به این معناست که هیچ ماژولی به نام جنگو وجود ندارد و جنگو به درستی نصب نشده است.اگر در مراحل نصب مشکلی داشتید میتوانید روش های نصب متفاوتی را امتحان کنید که در لینک روبرو قابل مطالعه میباشد.https://docs.djangoproject.com/en/5.0/intro/install/نکته: تمام پکیج های استفاده شده در این فصل با شماره نسخه آن در فایل requirements.txt سورس کد پروژه فصل ۱ قرار دارد. (لینک دسترسی به سورس کد پروژه این فصل)همچنین شما میتوانید نصب پکیج ها را بصورت قدم به قدم با روند آموزشی پیش بروید و یا بصورت یکجا با دستور زیر تمامی پکیج های فایل نیازمندی ها را نصب کنید:pip install -r requirements.txtمطالعه ادامه ترجمه کتابپست قبلی: (فصل اول - اپیزود ۱ - نصب پایتون در ویندوز/لینوکس/مک)پست بعدی: (فصل اول - اپیزود ۳ - معرفی جنگو ۵ و ویژگی های جدید جنگو)</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Thu, 14 May 2026 01:08:00 +0330</pubDate>
            </item>
                    <item>
                <title>فصل اول - اپیزود ۱ - ترجمه کتاب Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/httpsvirgooliorezarezaeedev%D9%81%D8%B5%D9%84-%D8%A7%D9%88%D9%84-%D8%A7%D9%BE%DB%8C%D8%B2%D9%88%D8%AF-%DB%B1-%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-%D8%AC%D9%86%DA%AF%D9%88-%DB%B5-%D8%A8%D8%A7-%D9%85%D8%AB%D8%A7%D9%84-install-python-virtualenv-ahda7rrtzdtn-ahda7rrtzdtn-ahda7rrtzdtn-ahda7rrtzdtn</link>
                <description>ترجمه کتاب جنگو ۵ با مثال - Django 5 by example - فصل اول اپیزود اولفصل اول ترجمه کتاب Django 5 By Example اثر آنتونیو مله شروع میکنیم و این کتاب رو فصل به فصل ترجمه میکنم و هر فصل رو در چند اپیزود به ترتیب منتشر میکنم که ترتیب مطالب و صفحات رو متوجه بشید.فصل ۱ - ساخت یک اپلیکیشن وبلاگدر این کتاب یاد می‌گیرید چگونه با استفاده از فریم‌ورک Django پروژه‌های وب حرفه‌ای بسازید. در این فصل اول، قدم‌به‌قدم با اجزای اصلی یک برنامه Django آشنا می‌شوید؛ از نصب اولیه گرفته تا راه‌اندازی و آماده‌سازی برای اجرا.اگر هنوز Django را روی سیستم خود نصب نکرده‌اید، در بخش «نصب Django» نحوه نصب آن به‌صورت کامل توضیح داده شده است.قبل از اینکه اولین پروژه Django خود را شروع کنیم، بهتر است بدانیم در این فصل قرار است چه چیزهایی یاد بگیریم. این فصل یک دید کلی از ساختار و نحوه کار Django به شما می‌دهد و اجزای اصلی لازم برای ساخت یک وب‌اپلیکیشن کامل را معرفی می‌کند. این اجزا شامل موارد زیر هستند:مدل‌ها (Models)، قالب‌ها (Templates)، ویوها (Views) و آدرس‌ها (URLs).همچنین در این فصل درک بهتری از نحوه کار Django و ارتباط بین بخش‌های مختلف آن پیدا می‌کنید.در ادامه با تفاوت بین «پروژه» (Project) و «اپلیکیشن» (Application) در Django آشنا می‌شوید و مهم‌ترین تنظیمات این فریم‌ورک را بررسی می‌کنید.در طول این فصل یک اپلیکیشن ساده برای وبلاگ می‌سازیم. این وبلاگ به کاربران اجازه می‌دهد همه نوشته‌های منتشرشده را ببینند و هر پست را به‌صورت جداگانه مطالعه کنند. علاوه بر این، یک پنل مدیریت ساده نیز ایجاد می‌کنیم تا بتوانید پست‌های وبلاگ را مدیریت و منتشر کنید.در دو فصل بعدی، همین اپلیکیشن وبلاگ را گسترش می‌دهیم و قابلیت‌های پیشرفته‌تری به آن اضافه خواهیم کرد.این فصل را مثل یک نقشه‌راه در نظر بگیرید؛ مسیری که قدم‌به‌قدم شما را به ساخت یک اپلیکیشن کامل و کاربردی با Django می‌رساند. اگر در ابتدا بعضی مفاهیم یا بخش‌ها کمی مبهم به نظر برسند، نگران نباشید. در طول کتاب هرکدام از این بخش‌ها را با جزئیات کافی بررسی می‌کنیم تا کاملاً روشن شوند.در این فصل، با موضوعات زیر آشنا می‌شوید:نصب Pythonایجاد یک محیط مجازی (Virtual Environment) در پایتوننصب Djangoایجاد و تنظیم یک پروژه Djangoساخت یک اپلیکیشن در Djangoطراحی مدل‌های دادهایجاد و اعمال مهاجرت‌های مدل (Migrations)راه‌اندازی بخش مدیریت (Admin) برای مدل‌هاکار با QuerySet‌ها و مدیرهای مدل (Model Managers)ساخت ویوها، قالب‌ها و مسیرها (Views, Templates, URLs)درک چرخه درخواست/پاسخ در Djangoدر پایان این بخش، کار را با نصب Python روی سیستم‌تان شروع کنید.همچنین سورس‌کد پروژه این فصل رو میتونید از لینک روبرو در گیتهاب دانلود کنید. (سورس‌کد فصل اول)اسامی تمام پکیج‌های پایتونی که در این فصل استفاده می‌شوند، در فایلrequirements.txtقرار داده شده‌اند. این فایل در پوشه پروژه این فصل وجود دارد.شما می‌توانید طبق راهنمایی‌های هر بخش، پکیج‌ها را به‌صورت جداگانه نصب کنید. اما یک راه ساده‌تر هم وجود دارد: نصب همه آن‌ها به‌صورت یکجا.برای این کار کافی است دستور زیر را اجرا کنید:python -m pip install -r requirements.txtبا اجرای این دستور، pip تمام کتابخانه‌های موردنیاز پروژه را بر اساس فایل requirements.txt دانلود و نصب می‌کند.نصب پایتون:جنگو 5 از پایتون نسخه های ۳.۱۰، ۳.۱۱ و ۳.۱۲ پشتیبانی میکند. در مثال‌های این کتاب، از پایتون 3.12 استفاده خواهیم کرد.اگر از لینوکس یا مک استفاده می‌کنید، احتمال زیادی وجود دارد که پایتون از قبل روی سیستم شما نصب باشد. اما اگر کاربر ویندوز هستید، می‌توانید فایل نصبی Python را از وب‌سایت رسمی پایتون دانلود کنید. (دانلود فایل نصبی پایتون)برای شروع، ترمینال یا خط فرمان سیستم خود را باز کنید:در مک کلیدهای Command + Space را بزنید، عبارت Terminal را جستجو و برنامه Terminal.app را اجرا کنید.در ویندوز منوی Start را باز کرده و عبارتpowers را جستجو کنید، سپس برنامه Windows PowerShell را اجرا کنید.همچنین می‌توانید با جستجوی cmd، محیط ساده‌تر Command Prompt را باز کنید.بعد از باز کردن ترمینال، برای بررسی نصب بودن Python 3 دستور زیر را اجرا کنید:python3 --versionاگر خروجی مشابه زیر را مشاهده کردید، یعنی Python 3 روی سیستم شما نصب است:Python 3.12.3اگر خطا دریافت کردید، به‌جای python3 دستور python را امتحان کنید. در ویندوز هم بهتر است از دستور py استفاده کنید.اگر نسخه پایتون نصب‌شده شما پایین‌تر از 3.12 است یا پایتون روی سیستم شما نصب نیست، نسخه پایتون ۳.۱۲ را از سایت رسمی دانلود و نصب کنید. (دانلود پایتون از وبسایت رسمی)در این صفحه، نسخه‌های مخصوص ویندوز، لینوکس و مک در دسترس هستند.اگر از لینوکس یا مک استفاده می‌کنید ممکن است نسخه پیش‌فرض پایتون سیستم شما هنوز پایتون نسخه ۲ باشد، باید برای اجرای نسخه جدید از دستور python3 استفاده کنید.توجه داشته باشید که پشتیبانی رسمی از پایتون نسخه ۲ از ژانویه ۲۰۲۰ به پایان رسیده و دیگر نباید از آن استفاده شود.در ویندوز، دستور python به فایل اجرایی نسخه پیش‌فرض پایتون که روی سیستم نصب شده اشاره می‌کند، اما دستور py در واقع لانچر پایتون است.لانچر پایتون برای ویندوز از نسخه Python 3.3 معرفی شد. این ابزار به‌صورت خودکار بررسی می‌کند چه نسخه‌هایی از پایتون روی سیستم شما نصب شده‌اند و اجرای دستورات را به جدیدترین نسخه موجود هدایت می‌کند.به همین دلیل، اگر از ویندوز استفاده می‌کنید، پیشنهاد می‌شود همیشه از دستور py استفاده کنید.برای اطلاعات بیشتر درباره لانچر پایتون در ویندوز، می‌توانید مستندات رسمی را مطالعه کنید: (مستندات رسمی لانچر پایتون در ویندوز)در ادامه، قرار است یک محیط مجازی پایتون (Python Virtual Environment) برای پروژه ایجاد کنیم و کتابخانه‌های موردنیاز را نصب کنیم.ایجاد محیط مجازی پایتون برای پروژه:وقتی با پایتون برنامه می‌نویسی میکنید، معمولاً از پکیج‌ها و ماژول‌هایی استفاده می‌کنید که جزو کتابخانه استاندارد پایتون نیستند. از طرفی ممکن است هر پروژه به نسخه متفاوتی از یک پکیج نیاز داشته باشد.مشکل اینجاست که اگر یک ماژول را به‌صورت سراسری روی سیستم نصب کنید، فقط یک نسخه از آن قابل استفاده خواهد بود. در نتیجه اگر برای یک پروژه نسخه جدیدتری از یک پکیج را نصب یا به‌روزرسانی کنید، ممکن است پروژه‌های دیگر که به نسخه قدیمی‌تر همان پکیج وابسته هستند دچار مشکل شوند.برای حل این مسئله، میتوانید از قابلیتی به نام محیط مجازی یا Virtual Environment در پایتون استفاده کنید.با استفاده از محیط مجازی، می‌توانید پکیج‌های موردنیاز هر پروژه را در یک فضای جدا و ایزوله نصب کنید، بدون اینکه روی نصب پایتون اصلی سیستم شما تأثیر بگذارد. هر محیط مجازی، نسخه اجرایی پایتون مخصوص خودش را دارد و مجموعه پکیج‌های نصب‌شده آن نیز به‌صورت مستقل در مسیر site-packages همان محیط نگهداری می‌شود.پایتون از نسخه 3.3 به بعد، به‌صورت پیش‌فرض کتابخانه venv را در اختیار شما قرار می‌دهد. این ابزار برای ساخت محیط‌های مجازی سبک و ایزوله استفاده می‌شود.با استفاده از venv می‌توانید برای هر پروژه، پکیج‌ها و نسخه‌های مخصوص همان پروژه را داشته باشید. یکی دیگر از مزیت‌های مهم آن این است که برای نصب پکیج‌ها داخل محیط مجازی، معمولاً نیازی به دسترسی ادمین یا Administrator ندارید.اگر از لینوکس یا مک استفاده می‌کنید، برای ساخت یک محیط مجازی ایزوله از دستور زیر استفاده کنید:python -m venv my_envنکته: به یاد داشته باشید اگر سیستم عامل شما به‌طور پیش‌فرض با Python 2 عرضه شده و خودتان Python 3 را نصب کرده‌اید، باید به‌جای دستورpython از python3 استفاده کنید.(توضیح کوتاه مترجم: در بسیاری از سیستم‌های لینوکسی قدیمی، دستور python به Python 2 اشاره می‌کند)اگر از ویندوز استفاده می‌کنید، دستور زیر را اجرا کنید:py -m venv my_envاین دستور از Python Launcher در ویندوز استفاده می‌کند.دستوری که در مرحله قبل اجرا کردید، یک محیط مجازی پایتون در پوشه‌ای به نام my_env ایجاد می‌کند.تا زمانی که محیط مجازی شما فعال است، کتابخانه ها و پکیج هایی که نصب میکنید در مسیر پکیج های محیط مجازی قرار میگیرند. آدرس مسیر بدین صورت است: my_env/lib/python3.12/site-packagesبه این ترتیب، پکیج‌های پروژه شما از سایر پروژه‌ها و همچنین از نصب اصلی Python روی سیستم جدا خواهند بود.برای فعال کردن محیط مجازی:در لینوکس و مک از دستور زیر استفاده کنید:source my_env/bin/activate• در Windows از دستور زیر استفاده کنید:.\my_env\Scripts\activateبعد از فعال‌سازی، نام محیط مجازی در ابتدای خط فرمان نمایش داده می‌شود؛ چیزی شبیه به این:(my_env) zenx@pc:~ zenx$وجود (my_env) یعنی اکنون تمام پکیج‌هایی که نصب می‌کنید داخل همین محیط مجازی نصب خواهند شد.هر زمان که خواستید از محیط مجازی خارج شوید، کافی است دستور زیر را اجرا کنید:deactivateبرای مطالعه بیشتر درباره venv می‌توانید مستندات رسمی پایتون را بخوانید: (مستدات رسمی venv در پایتون)سخن مترجم: برای این اپیزود کافیه. تا اینجا کمی با پایتون و محیط مجازیش در سیستم عامل های مختلف آشنا شدیم . انشاالله اپیزود بعدی ترجمه بخش نصب جنگو و ایجاد پروژه جنگو را باهاتون به اشتراک میگذارم.درنهایت اگر سوال فنی و یا درمورد ترجمه و کتاب دارید و یا ایراد و مشکل و پیشنهادی درمورد محتوای ترجمه میبینید کامنت بگزارید.- با سپاس از حسن توجه تون💐مطالعه ادامه ترجمه کتابپست قبلی: (معرفی کتاب Django 5 By Example)پست بعدی: (فصل اول - اپیزود ۲ - نصب جنگو و شیوه های آن)</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Tue, 12 May 2026 15:25:24 +0330</pubDate>
            </item>
                    <item>
                <title>ترجمه کتاب جنگو ۵ با مثال | Django 5 By Example</title>
                <link>https://virgool.io/@rezarezaeedev/%D8%AA%D8%B1%D8%AC%D9%85%D9%87-%DA%A9%D8%AA%D8%A7%D8%A8-%D8%AC%D9%86%DA%AF%D9%88-%DB%B5-%D8%A8%D8%A7-%D9%85%D8%AB%D8%A7%D9%84-django-5-by-example-tpen4nwcywuo</link>
                <description>کتاب جنگو ۵ با مثال - Django 5 By Example اثر آنتونیو ملهدر این سلسله پست ها قصد دارم ترجمه کتاب Django 5 by example اثر آنتونیو مله رو باهاتون به اشتراک بزارم.ابتدا خودم شروع به خوندن این کتاب کردم و سپس تصمیم گرفتم درکنار مطالعه خودم، ترجمه اش رو هم با شما به اشتراک بزارم بلکه به کامیونیتی پایتون و جنگو فارسی کمکی کرده باشم(در حد خودم).کتاب معروف و شناخته شده ای هست اما به عنوان معرفی و یک تبلیغ واسه افرادی که این کتاب رو نمیشناسند توضیحاتی میدهم:کتاب به وسیله ۴ پروژه واقعی روی بخش‌های مهمی مثل:ساخت اپلیکیشن‌های وب با Djangoکار با مدل‌ها، ویوها، تمپلیت‌هااحراز هویت کاربرانپنل ادمینORMکش، Redis، CeleryAPI و قابلیت‌های عملی برای محصول واقعیتمرکز دارد.سبک کتاب بیشتر کاربردی و hands-on است تا آکادمیک. یعنی کتاب بیشتر روی یادگیری با ساختن تمرکز دارد، نه فقط توضیح مفاهیم.موضوعات ۴ پروژه هم به شرح ذیل است:وبلاگ (Blog Application)یک وبلاگ کامل برای یادگیری مبانی جنگو: مدل‌ها، ویوها، URLها، فرم‌ها، سیستم کامنت، تگ‌گذاری و جستجو.(فصل ۱ تا ۳)شبکه اجتماعی تصویری (Image Bookmark / Social Website)سایتی شبیه بوکمارک یا اشتراک‌گذاری تصویر که در آن کاربران ثبت‌نام می‌کنند، تصویر ذخیره می‌کنند، لایک می‌زنند و فعالیت کاربران دنبال می‌شود.(فصل ۴تا ۷)فروشگاه آنلاین (Online Shop / E-commerce)یک فروشگاه اینترنتی با سبد خرید، سفارش، کوپن تخفیف، اتصال به درگاه پرداخت و مدیریت فرایند خرید.(فصل ۸تا ۱۱)سامانه آموزش آنلاین (E-learning Platform)پلتفرمی برای ساخت و فروش یا ارائه دوره‌ها؛ شامل دوره، ماژول، محتوا، ثبت‌نام کاربران و مدیریت آموزشی.(فصل ۱۲تا ۱۷).حدود ۸۰۰ صفحه است این کتاب(نسخه اصلی).فایل این کتابم میتونید از وبسایت دانلودلی یا فروشگاه فقط-کتاب دانلود کنید. یا حتی نسخه ترجمه بهترشم آقای حسین یعسوبی زحمت کشیده و در دیجی کالا و وبسایت انتشارات پندار پارس موجود هست.درنهایت دوست دارم بهترین ترجمه این کتاب رو منتشر کنم و با دانش ناقصم هرگز قادر به این امر نیستم و ممنون میشم اگر پیشنهادی دارید و یا مشکلی در محتوا برخورد کردید حتما بهم اطلاع بدید تا با کمک شما این ترجمه به بهترین شکل منتشر بشه.ادامه کتاب را از لینک زیر بخوانید:پست بعدی: نصب پایتون و محیط مجازی آن</description>
                <category>رضا رضایی</category>
                <author>رضا رضایی</author>
                <pubDate>Sat, 09 May 2026 02:30:16 +0330</pubDate>
            </item>
            </channel>
</rss>