پردازش شرطی ویوها در جنگو: ETag، Last-Modified و دکوراتور condition

این مقاله نحوهٔ پردازش شرطی درخواست‌های HTTP در جنگو را توضیح می‌دهد. موضوعاتی مانند هدرهای ETag و Last-Modified، دکوراتور condition، دکوراتورهای etag و last_modified، استفاده از پردازش شرطی در متدهای غیرایمن (POST/PUT/DELETE) و مقایسهٔ آن با ConditionalGetMiddleware بررسی می‌شوند.

پردازش شرطی جنگو، ETag، Last-Modifiedcondition decorator، If-Modified-Since، If-None-Match304 Not Modified، 412 Precondition Failed

~3 min read · Updated Mar 15, 2026

مقدمه

کلاینت‌های HTTP می‌توانند هدرهایی ارسال کنند که نشان می‌دهد نسخهٔ قبلی یک منبع را قبلاً دریافت کرده‌اند. این کار باعث می‌شود سرور در صورت عدم تغییر محتوا، پاسخ کامل ارسال نکند. جنگو از طریق هدرهای ETag و Last-Modified از این قابلیت پشتیبانی می‌کند.

اگر کلاینت هدرهایی مانند If-Modified-Since یا If-None-Match ارسال کند، جنگو می‌تواند به‌جای پاسخ کامل، وضعیت 304 Not Modified برگرداند. اگر نسخهٔ منبع تغییر کرده باشد، ممکن است وضعیت 412 Precondition Failed بازگردانده شود.


دکوراتور condition

برای کنترل دقیق‌تر، جنگو دکوراتور condition() را ارائه می‌دهد. این دکوراتور دو تابع اختیاری دریافت می‌کند:

  • etag_func: تولیدکنندهٔ مقدار ETag
  • last_modified_func: تولیدکنندهٔ زمان آخرین تغییر

این توابع همان آرگومان‌های ویو را دریافت می‌کنند و به جنگو اجازه می‌دهند قبل از اجرای کامل ویو، بررسی کنند که آیا محتوا تغییر کرده است یا نه.

امضا


condition(etag_func=None, last_modified_func=None)

مثال

فرض کنید صفحهٔ اصلی یک وبلاگ فقط زمانی تغییر می‌کند که یک پست جدید منتشر شود:


def latest_entry(request, blog_id):
    return Entry.objects.filter(blog=blog_id).latest("published").published

می‌توان از این تابع برای پردازش شرطی استفاده کرد:


from django.views.decorators.http import condition

@condition(last_modified_func=latest_entry)
def front_page(request, blog_id):
    ...

هشدار دربارهٔ ترتیب دکوراتورها

دکوراتورهایی مانند vary_on_cookie()، vary_on_headers() و cache_control() باید قبل از condition() قرار بگیرند. زیرا اگر condition پاسخ 304 بدهد، دکوراتورهای زیر آن اجرا نمی‌شوند.


میان‌بُرها: etag() و last_modified()

اگر فقط یکی از مقادیر ETag یا Last-Modified را نیاز دارید، می‌توانید از دکوراتورهای ساده‌تر استفاده کنید:


etag(etag_func)
last_modified(last_modified_func)

مثال


@last_modified(latest_entry)
def front_page(request, blog_id):
    ...

از chain کردن etag و last_modified خودداری کنید

این کار اشتباه است:


@etag(etag_func)
@last_modified(last_modified_func)
def my_view(request):
    ...

هر دکوراتور مستقل عمل می‌کند و ممکن است نتیجهٔ اشتباه بدهد. برای استفاده از هر دو مقدار، فقط از condition() استفاده کنید.


استفاده در متدهای غیرایمن (POST/PUT/DELETE)

پردازش شرطی فقط برای GET و HEAD نیست. در متدهای PUT، POST و DELETE نیز می‌تواند از تغییرات ناخواسته جلوگیری کند.

مثال

  1. کلاینت GET می‌زند و ETag = "abcd1234" دریافت می‌کند.
  2. کلاینت PUT می‌زند و هدر If-Match: "abcd1234" ارسال می‌کند.
  3. سرور ETag جدید را محاسبه می‌کند.
  4. اگر تغییر کرده باشد → 412 Precondition Failed.
  5. کلاینت GET جدید می‌زند تا نسخهٔ تازه را دریافت کند.

این روش از overwrite شدن داده‌های تغییر کرده جلوگیری می‌کند.

هدرهای اعتبارسنجی در متدهای غیرایمن

دکوراتور condition() فقط برای GET و HEAD هدرهای ETag و Last-Modified را تنظیم می‌کند. اگر می‌خواهید در PUT یا POST هم ارسال شوند، باید در ویو تنظیم کنید.


مقایسه با ConditionalGetMiddleware

جنگو middleware مخصوص GET شرطی دارد: ConditionalGetMiddleware. اما محدودیت‌هایی دارد:

  • برای همهٔ ویوها اعمال می‌شود
  • از اجرای ویو جلوگیری نمی‌کند (حتی اگر گران باشد)
  • فقط برای GET مناسب است

از condition() استفاده کنید اگر:

  • می‌توانید ETag یا Last-Modified را سریع محاسبه کنید
  • ویو سنگین است
  • نیاز به پردازش شرطی برای PUT/POST/DELETE دارید

از middleware استفاده کنید اگر:

  • ویوها سریع هستند
  • فقط GET شرطی نیاز دارید

جمع‌بندی

پردازش شرطی ویوها در جنگو ابزار قدرتمندی برای بهینه‌سازی عملکرد و جلوگیری از تغییرات ناخواسته است. با استفاده از ETag، Last-Modified، دکوراتور condition و هدرهای شرطی HTTP، می‌توانید از ارسال داده‌های غیرضروری جلوگیری کنید و هم‌زمان یک سیستم امن و سازگار با استانداردهای HTTP بسازید.

Written & researched by Dr. Shahin Siami

Related Articles

فریم‌ورک Tasks در Django: راهنمای کامل اجرای کارهای پس‌زمینه در Django 6.0

Django 6.0 فریم‌ورک Tasks را معرفی کرده است؛ سیستمی داخلی برای تعریف و صف‌بندی کارهای پس‌زمینه خارج از چرخهٔ request–response. این مقاله نحوهٔ کار Tasks، پیکربندی backendها، تعریف و enqueue کردن Taskها، استفاده از context، و ادغام با سیستم‌های Worker خارجی را توضیح می‌دهد.

Continue

پشتیبانی Asynchronous در Django: راهنمای کامل Async Views، ORM، Middleware، عملکرد و ایمنی

این مقاله پشتیبانی Django از برنامه‌نویسی غیرهم‌زمان (async) را توضیح می‌دهد. موضوعاتی مانند async views، اجرای Django تحت ASGI، رفتار middleware، قابلیت‌های ORM غیرهم‌زمان، sync_to_async، مدیریت قطع اتصال، نکات عملکردی، و مکانیزم‌های ایمنی Django برای جلوگیری از استفادهٔ ناامن async بررسی می‌شوند.

Continue

System Check Framework در Django: راهنمای کامل نوشتن، ثبت، اجرا و تست چک‌های سیستمی

System Check Framework در Django مجموعه‌ای از بررسی‌های استاتیک برای تشخیص مشکلات رایج در پروژه است. این مقاله نحوهٔ اجرای چک‌ها، نوشتن چک‌های سفارشی، مدیریت پیام‌ها، برچسب‌گذاری چک‌ها، افزودن چک به مدل‌ها و فیلدها، و نوشتن تست‌های واحد و یکپارچه برای چک‌ها را توضیح می‌دهد.

Continue

سیگنال‌ها در Django: راهنمای کامل استفاده، اتصال، ارسال و مدیریت Signalها

این مقاله سیستم سیگنال‌های Django را توضیح می‌دهد؛ مکانیزمی برای اطلاع‌رسانی رویدادها بین بخش‌های مختلف برنامه بدون ایجاد وابستگی مستقیم. موضوعاتی مانند نحوهٔ اتصال receiverها، استفاده از decorator، مدیریت senderهای خاص، محل مناسب قرارگیری کد سیگنال‌ها، هشدارهای مهم، و بهترین شیوه‌ها بررسی می‌شوند.

Continue

آشنایی کامل با Django Settings: پیکربندی، مدیریت محیط، و بهترین شیوه‌ها

این مقاله یک راهنمای جامع دربارهٔ سیستم تنظیمات در Django ارائه می‌دهد. موضوعاتی مانند ساختار فایل تنظیمات، نحوهٔ تعیین DJANGO_SETTINGS_MODULE، استفاده از settings در کد، امنیت، پیکربندی دستی با configure()، استفادهٔ مستقل از Django با django.setup() و ایجاد تنظیمات سفارشی بررسی می‌شوند.

Continue

سریال‌سازی و دسریال‌سازی در Django: راهنمای کامل کار با Serialization Framework

این مقاله سیستم سریال‌سازی Django را توضیح می‌دهد؛ از نحوهٔ تبدیل مدل‌ها به JSON، XML، YAML و JSONL گرفته تا دسریال‌سازی داده‌ها، سریال‌سازی فیلدهای انتخابی، کار با مدل‌های ارث‌بری، مدیریت روابط، و نکات مهم هنگام ذخیرهٔ داده‌های دسریال‌شده.

Continue