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 الكامل بالعربي.