on_delete=models.DB_CASCADE
خيارات الحذف على مستوى قاعدة البيانات (Django 6.1) on_delete=models.DB_CASCADE
منذ Django 6.1، يقبل on_delete قيمًا جديدة (DB_CASCADE وأخواتها) تُنفَّذ داخل قاعدة البيانات مباشرة عبر قيد ON DELETE، بدل جلب السجلات المرتبطة وحذفها من جهة Django.
بعكس CASCADE التقليدية التي تجعل Django يجلب كل السجلات المرتبطة أولًا ثم يحذفها، القيم الجديدة (DB_CASCADE، DB_PROTECT، DB_RESTRICT، DB_SET_NULL، DB_SET_DEFAULT، DB_DO_NOTHING) تُفوّض الحذف بالكامل لقيد قاعدة البيانات نفسه — أسرع بكثير مع كميات بيانات كبيرة، لكن بلا إطلاق إشارات pre_delete/post_delete للسجلات المرتبطة، وبنتيجة delete() جزئية لا تُحصي ما حذفه القيد مباشرة.
الصياغة
from django.db import models field = models.ForeignKey(Other, on_delete=models.DB_CASCADE)
📄 مثال
class Post(models.Model):
author = models.ForeignKey(
"Author",
on_delete=models.DB_CASCADE, # تنفيذ داخل قاعدة البيانات مباشرة
)
author.delete()
# (1, {'blog.Author': 1}) — لا يُحصي منشورات المؤلف المحذوفة بالقيدأهم المعاملات
| المعامل | الوظيفة |
|---|---|
| models.DB_CASCADE | حذف السجلات المرتبطة عبر قيد قاعدة البيانات مباشرة — نظير CASCADE لكن بتنفيذ SQL بحت |
| models.DB_PROTECT / DB_RESTRICT | منع الحذف عبر قيد قاعدة البيانات — الاستثناء يأتي من قاعدة البيانات (IntegrityError) لا من Django |
| models.DB_SET_NULL / DB_SET_DEFAULT / DB_DO_NOTHING | نظائر SET_NULL/SET_DEFAULT/DO_NOTHING التقليدية، منفَّذة على مستوى قاعدة البيانات |
💡 نصائح عملية
- استخدمها لعلاقات بحجم بيانات كبير حيث لا يعتمد منطقك على إشارات pre_delete/post_delete للسجلات المرتبطة
- أبقِ الخيارات التقليدية (CASCADE, PROTECT, ...) حيث تحتاج منطق إشارات مخصّص أو تتبعًا دقيقًا لكل ما حُذف
⚠️ أخطاء شائعة
- استبدال CASCADE بـ DB_CASCADE بمشروع قائم يعتمد على post_delete لتنظيف ملفات مرتبطة — يتوقف هذا المنطق عن العمل بصمت للسجلات المحذوفة بالقيد
- الاعتماد على قاموس delete() المُرجَع لعدّ كل ما تأثّر بعملية تستخدم خيار DB-level — العدّ جزئي ولا يشمل ما حذفته قاعدة البيانات مباشرة
خصائص ذات صلة
🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار DJANGO الكامل بالعربي.