تخطَّ إلى المحتوى

fetch_mode()

أنماط جلب الحقول الجديدة (Django 6.1) fetch_mode()

fetch_mode() تضبط سلوك الجلب التلقائي للحقول غير المُجلَبة على مستوى الاستعلام كاملًا — حل جديد لمشكلة N+1 لا يتطلّب تحديد اسم كل حقل صراحة كـ select_related/prefetch_related.

ثلاثة أنماط جاهزة بـ django.db.models: FETCH_ONE (الافتراضي، سلوك Django التقليدي — يجلب الحقل للكائن الحالي فقط)، FETCH_PEERS (يجلب الحقل الناقص لكل كائنات نفس QuerySet دفعة واحدة، مثل prefetch_related تلقائي)، وRAISE (يرفع FieldFetchBlocked بدل تنفيذ استعلام إضافي، لكشف استعلامات غير مقصودة). Django ينقل النمط لأي كائنات مرتبطة تُجلَب بعدها، فيسري على شجرة العلاقات كاملة.

الصياغة

Model.objects.fetch_mode(models.FETCH_PEERS)
Model.objects.fetch_mode(models.RAISE)

📄 مثال

from django.db import models

# بدون تحديد أي حقل مسبقًا — استعلامان فقط بالمجمل
for book in Book.objects.fetch_mode(models.FETCH_PEERS):
    print(book.author.name)

أهم المعاملات

المعاملالوظيفة
models.FETCH_ONEالافتراضي — يجلب الحقل الناقص للكائن الحالي فقط (سلوك Django القديم)
models.FETCH_PEERSيجلب الحقل الناقص لكل كائنات نفس QuerySet معًا، لا للكائن الحالي وحده
models.RAISEيرفع FieldFetchBlocked عند أي وصول لحقل غير مُجلَب، بدل تنفيذ استعلام إضافي

💡 نصائح عملية

  • اضبط النمط الافتراضي لنموذج كامل عبر Manager مخصّص يستدعي fetch_mode() داخل get_queryset()، بدل تكراره بكل استعلام
  • استخدم RAISE بالاختبارات لكشف استعلامات N+1 خفية قبل الوصول للإنتاج

⚠️ أخطاء شائعة

  • الظن أنها تُلغي حاجة select_related/prefetch_related كليًا — تبقى الأدق حين تعرف احتياجك مسبقًا؛ fetch_mode() طبقة حماية إضافية لا بديل شامل
  • استخدام RAISE بكود إنتاج عادي دون التعامل مع FieldFetchBlocked — يحوّل أي وصول غير مُجهَّز لخطأ فوري بدل استعلام إضافي يعمل رغم بطئه

خصائص ذات صلة

🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار DJANGO الكامل بالعربي.