آنچه در این مقاله میخوانید [پنهانسازی]
اگر به دنبال ارتقا مهارت های فنی و ساخت سرویس های سریع تر و پایدارتر هستید، آشنایی با قابلیت های جدید Django یک مزیت جدی محسوب می شود. در این مطلب به مهم ترین تغییرات و امکانات نسخه های اخیر می پردازیم و با مثال های کاربردی نشان می دهیم چطور همین امروز از آن ها در پروژه های واقعی استفاده کنید تا عملکرد بهتر، کدنویسی تمیزتر و نگهداری ساده تری داشته باشید.
سرفصل های مقاله
- پشتیبانی بالغ از async و ASGI در هسته
- ORM ناهمگام برای پرس و جوهای بدون بلاک شدن
- GeneratedField برای ستون های محاسبه شده در دیتابیس
- STORAGES تنظیم یکپارچه برای فایل ها و رسانه
- zoneinfo و مدیریت بهتر زمان
- JSONField بین دیتابیس ها و کوئری های ساخت یافته
- ایندکس ها و قیود پیشرفته برای کارایی و صحت داده
- امنیت رمز عبور با scrypt و Argon2
- تست های ناهمگام با AsyncClient
- پاسخ دهی جریانی با StreamingHttpResponse
- بهبود تجربه توسعه در Admin مدرن
- راهکارهای مهاجرت تدریجی و نکات عملی
- جمع بندی
پشتیبانی بالغ از async و ASGI در هسته
هسته جنگو مدت ها است از ASGI پشتیبانی می کند، اما در نسخه های اخیر بلوغ پیاده سازی های ناهمگام بسیار بیشتر شده است. استفاده از async view ها به شما کمک می کند درخواست های I O محور مثل فراخوانی API های خارجی یا اتصال به سرویس های پیام را بدون بلاک شدن پردازش کنید. نکته مهم این است که فقط زمانی از async استفاده کنید که عملیات شما منتظر شبکه یا دیسک است و نه برای محاسبات CPU محور.
# views.py
from django.http import JsonResponse
import httpx
async def currency_rate(request):
async with httpx.AsyncClient(timeout=5) as client:
r = await client.get("https://api.exchangerate.host/latest?base=USD")
data = r.json()
return JsonResponse({"eur": data["rates"]["EUR"]})
این الگو برای سرویس های ترکیبی که همزمان به چند منبع داده متصل می شوند ایده ال است و موجب استفاده بهتر از منابع سرور می شود.
ORM ناهمگام برای پرس و جوهای بدون بلاک شدن
بهبودهای اخیر در ORM ناهمگام باعث شده فراخوانی های متداول مانند گرفتن رکورد، ساختن شی و شمارش با نسخه های async در دسترس باشد. این یعنی در یک view ناهمگام دیگر لازم نیست عملیات دیتابیس را با executor اجرا کنید و می توانید مستقیم await بنویسید.
# views.py
from django.http import JsonResponse
from shop.models import Product
async def product_detail(request, pk):
product = await Product.objects.aget(pk=pk)
await Product.objects.filter(pk=pk).aupdate(views_count=product.views_count + 1)
return JsonResponse({"name": product.name, "price": float(product.price)})
هنگام استفاده ترکیبی از ORM ناهمگام و همگام دقت کنید. در view های async از متدهای a… و در view های sync از متدهای معمولی استفاده کنید تا دچار خطا و افت کارایی نشوید.
GeneratedField برای ستون های محاسبه شده در دیتابیس
یکی از تحولات مهم مدل داده در نسخه های جدید، امکان تعریف ستون های محاسبه شونده در سطح پایگاه داده است. با GeneratedField می توانید بر اساس سایر فیلدها مقداری را محاسبه و ذخیره یا فقط به صورت مجازی ارائه کنید. این کار منطق تجمعی و سنگین را از برنامه به دیتابیس منتقل می کند و سازگاری نتایج را بالا می برد.
# models.py
from django.db import models
from django.db.models import F
class OrderItem(models.Model):
price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.PositiveIntegerField()
total = models.GeneratedField(
expression=F("price") * F("quantity"),
output_field=models.DecimalField(max_digits=12, decimal_places=2),
db_persist=True, # در صورت نیاز مقدار محاسبه شده ذخیره می شود
)
در میان قابلیت های جدید Django این ویژگی برای گزارش گیری سریع، کاهش بار پردازش در لایه برنامه و جلوگیری از ناسازگاری داده ها بسیار کلیدی است.
STORAGES تنظیم یکپارچه برای فایل ها و رسانه
پیکربندی ذخیره سازی فایل ها به کمک تنظیم STORAGES ساده تر و شفاف تر شده است. به جای استفاده از مقادیر جداگانه، اکنون می توانید backend پیش فرض فایل ها و staticfiles را در یک دیکشنری مشخص کنید. این تغییر مهاجرت بین فضای محلی و فضای ابری یا استفاده از استراتژی های هش دار را راحت می کند.
# settings.py
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
"OPTIONS": {"location": BASE_DIR / "media"},
},
"staticfiles": {
"BACKEND": "django.contrib.staticfiles.storage.ManifestStaticFilesStorage",
},
}
- مسیر ذخیره فایل های کاربر را مشخص کنید.
- برای staticfiles از Manifest استفاده کنید تا کش مرورگر به شکل مطمئن مدیریت شود.
- در محیط تولید می توانید backend ها را با مقادیر مخصوص سرور جایگزین کنید.
zoneinfo و مدیریت بهتر زمان
جنگو اکنون به صورت پیش فرض از zoneinfo استاندارد کتابخانه استاندارد پایتون برای منطقه های زمانی استفاده می کند. این یعنی وابستگی به کتابخانه های جانبی کاهش یافته و سازگاری زمانی سیستم با آپدیت های پایتون ساده تر شده است. برای کار با زمان های آگاه به منطقه زمانی همچنان از ابزارهای کمکی django.utils.timezone استفاده کنید.
# نمونه ای از کار با زمان آگاه
from datetime import datetime
from zoneinfo import ZoneInfo
from django.utils import timezone
now_utc = timezone.now()
tehran_time = now_utc.astimezone(ZoneInfo("Asia/Tehran"))
print(tehran_time.strftime("%Y-%m-%d %H:%M"))
استانداردسازی زمان ها باعث می شود برنامه در محیط های چند سروری و چند منطقه ای قابل اتکا تر عمل کند.
JSONField بین دیتابیس ها و کوئری های ساخت یافته
JSONField اکنون در اکثر پایگاه های داده پشتیبانی می شود و نوشتن ساختارهای منعطف را بدون طراحی جداول متعدد ممکن می کند. از طرفی ORM ابزارهای قدرتمندی برای جستجو در داخل JSON ارائه می دهد که توسعه API های پویا را ساده می کند.
# models.py
from django.db import models
class Event(models.Model):
meta = models.JSONField(default=dict)
created_at = models.DateTimeField(auto_now_add=True)
# کوئری روی داده های تو در تو
from django.db.models import Q
vip_events = Event.objects.filter(meta__contains={"tier": "vip"})
recent_with_source = Event.objects.filter(
Q(meta__source="mobile") & Q(created_at__gte="2026-01-01")
)
برای داده های نیمه ساخت یافته، JSONField تعادل خوبی میان چابکی توسعه و امکان جستجو ایجاد می کند، به ویژه وقتی به تدریج در حال تثبیت اسکیمای داده هستید.
ایندکس ها و قیود پیشرفته برای کارایی و صحت داده
ایجاد Index های تابعی و UniqueConstraint های شرطی به شما کمک می کند همزمان عملکرد کوئری ها را بهبود دهید و قواعد تجاری را در سطح دیتابیس enforce کنید. این رویکرد علاوه بر سرعت، جلوی داده های ناسازگار را نیز می گیرد.
# models.py
from django.db import models
from django.db.models import Q
from django.db.models.functions import Lower
class Customer(models.Model):
email = models.EmailField(unique=False)
is_active = models.BooleanField(default=True)
name = models.CharField(max_length=200)
class Meta:
indexes = [
models.Index(Lower("name"), name="idx_customer_name_lower"),
]
constraints = [
models.UniqueConstraint(
fields=["email"],
condition=Q(is_active=True),
name="uniq_active_email",
),
]
ایندکس تابعی Lower جستجوهای بدون توجه به حروف بزرگ و کوچک را سریع می کند. قید یکتا با شرط نیز فقط برای مشتریان فعال اعمال می شود و انعطاف پذیری بالایی دارد.
امنیت رمز عبور با scrypt و Argon2
جنگو از الگوریتم های مدرن مانند scrypt و Argon2 پشتیبانی می کند. این الگوریتم ها در برابر حملات brute force مقاوم تر هستند و امکان تنظیم هزینه محاسباتی را فراهم می کنند. پیشنهاد می شود اولویت را به Argon2 بدهید و سپس scrypt را فعال کنید تا سازگاری با گذرواژه های قدیمی حفظ شود.
# settings.py
PASSWORD_HASHERS = [
"django.contrib.auth.hashers.Argon2PasswordHasher",
"django.contrib.auth.hashers.ScryptPasswordHasher",
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
]
- در محیط تولید، منابع محاسباتی کافی برای این الگوریتم ها در نظر بگیرید.
- پس از تغییر hashers، کاربران به تدریج با اولین ورود گذرواژه خود را به الگوریتم جدید مهاجرت می دهند.
تست های ناهمگام با AsyncClient
همگام با رشد قابلیت های async، ابزار تست نیز توسعه پیدا کرده است. AsyncClient امکان نوشتن تست برای view ها و مسیرهای ناهمگام را فراهم می کند. تست به موقع رفتار async از باگ های پنهان جلوگیری می کند و اطمینان شما از عملکرد در بار واقعی را بالا می برد.
# tests.py
import pytest
from django.test import AsyncClient
from django.urls import reverse
@pytest.mark.asyncio
async def test_currency_rate():
client = AsyncClient()
url = reverse("currency_rate")
resp = await client.get(url)
assert resp.status_code == 200
data = resp.json()
assert "eur" in data
اگر از pytest استفاده می کنید، با افزونه های مربوطه اجرای تست های async ساده و خوانا می شود. در محیط های کوچک نیز تست ناهمگام با unittest استاندارد قابل انجام است.
پاسخ دهی جریانی با StreamingHttpResponse
وقتی خروجی شما حجیم یا تولید آن زمانبر است، پاسخ دهی جریانی می تواند تجربه کاربر را بهبود دهد. با StreamingHttpResponse می توانید داده را قطعه به قطعه ارسال کنید تا کاربر زودتر اولین بایت را دریافت کند و سرور نیز حافظه کمتری مصرف کند.
# views.py
from django.http import StreamingHttpResponse
import time
def stream_numbers(request):
def number_stream():
for i in range(1, 6):
yield f"chunk {i}\n"
time.sleep(1) # شبیه سازی کار زمانبر
return StreamingHttpResponse(number_stream(), content_type="text/plain")
در سرویس های گزارش گیری، export فایل های بزرگ یا ارسال رخدادها، استریم کردن پاسخ تاثیر محسوسی بر تجربه کاربری و منابع سرور دارد.
بهبود تجربه توسعه در Admin مدرن
رابط مدیریت جنگو طی نسخه های اخیر مدرن تر و پیکربندی پذیرتر شده است. از جستجوی سریع تر و فیلترهای سمت چپ گرفته تا قابلیت های autocomplete برای فیلدهای کلیدی، همه برای سریع تر شدن کار مدیران سامانه طراحی شده اند. با استفاده درست از list_select_related، prefetch_related و autocomplete_fields می توانید تعداد کوئری ها را کاهش دهید و صفحات سنگین را سبک کنید.
# admin.py
from django.contrib import admin
from .models import Customer, OrderItem
@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
list_display = ("id", "name", "email", "is_active")
search_fields = ("name", "email")
list_filter = ("is_active",)
autocomplete_fields = ()
@admin.register(OrderItem)
class OrderItemAdmin(admin.ModelAdmin):
list_display = ("id", "quantity", "total")
list_select_related = ()
با کمی تنظیم هوشمندانه، پنل مدیریت می تواند به ابزار تحلیلی سبک و سریع برای تیم شما تبدیل شود، بدون اینکه نیاز به توسعه رابط اختصاصی داشته باشید.
راهکارهای مهاجرت تدریجی و نکات عملی
برای استفاده سریع و ایمن از تغییرات جدید، مهاجرت تدریجی بهترین رویکرد است. ابتدا view های I O محور را به async تبدیل کنید، سپس در همان مسیر از ORM ناهمگام بهره ببرید. ایندکس ها و قیود را مرحله ای اضافه کنید تا رفتار کوئری ها را زیر نظر بگیرید و پس از اطمینان آن ها را به محیط تولید ببرید. در نهایت، تنظیم STORAGES و الگوریتم های رمز عبور را به نحوی انجام دهید که با استراتژی انتشار شما همخوانی داشته باشد.
- در هر تغییر، معیارهای عملکردی قبل و بعد را ثبت کنید.
- برای ویژگی های پایگاه داده، نسخه دیتابیس و سازگاری آن را بررسی کنید.
- پوشش تست مناسب به ویژه برای مسیرهای async را جدی بگیرید.
جمع بندی
تمرکز روی چند محور مشخص یعنی async در هسته و ORM، ستون های محاسبه شونده با GeneratedField، STORAGES یکپارچه، کار با زمان مبتنی بر zoneinfo، JSONField، ایندکس ها و قیود پیشرفته، امنیت بهتر گذرواژه و ابزار تست ناهمگام، به سرعت کیفیت پروژه های شما را بالا می برد. اگر بنا دارید بین گزینه ها اولویت بندی کنید، ابتدا سناریوهای I O محور را به async منتقل کنید و بعد سراغ داده و ذخیره سازی بروید. با شناخت و به کارگیری درست قابلیت های جدید Django می توانید بدون بازنویسی اساسی، تجربه کاربر و کارایی زیرساخت را یک پله ارتقا دهید.






