python - ماذا تفعل on_delete في نماذج Django
django-models (5)
إذا كنت تستخدم الفئة الأصل باعتبارها المفتاح الخارجي الذي تحتاج إليه (اسم الفئة الأصل ، on_delete = models.CASCADE) ، فإذا قمت بحذف نموذج الفئة الأصل ، فسيتم تلقائيًا حذف بيانات الفئة الفرعية المرتبطة بهذه الفئة الأصل.
أنا معتاد تمامًا على Django ، لكن لاحظت مؤخرًا وجود خيار
on_delete=models.CASCADE
مع النماذج ، لقد بحثت عن الوثائق لنفسه ولكن لم أجد أي شيء أكثر من:
تغيرت في جانغو 1.9:
يمكن الآن استخدام
on_delete
كوسيطة الموضعية الثانية (سابقًا ، كانت عادةً ما يتم تمريرها فقط كوسيطة كلمة أساسية). ستكون حجة مطلوبة في Django 2.0.
from django.db import models
class Car(models.Model):
manufacturer = models.ForeignKey(
'Manufacturer',
on_delete=models.CASCADE,
)
# ...
class Manufacturer(models.Model):
# ...
pass
ماذا يفعل on_delete؟ ( أعتقد الإجراءات التي يجب القيام بها إذا تم حذف النموذج )
ماذا تفعل
models.CASCADE
؟
(
أي تلميحات في الوثائق
)
ما هي الخيارات الأخرى المتاحة ( إذا كان تخميني صحيحًا )؟
أين توجد وثائق هذا؟
كما ذكرنا سابقًا ، ستحذف CASCADE السجل الذي يحتوي على مفتاح خارجي ويشير إلى كائن آخر تم حذفه. هكذا على سبيل المثال إذا كان لديك موقع عقاري ولديك خاصية تشير إلى مدينة
class City(models.Model):
# define model fields for a city
class Property(models.Model):
city = models.ForeignKey(City, on_delete = models.CASCADE)
# define model fields for a property
والآن عندما يتم حذف المدينة من قاعدة البيانات ، سيتم أيضًا حذف جميع الخصائص المرتبطة (مثل العقارات الموجودة في تلك المدينة) من قاعدة البيانات
الآن أريد أيضًا أن أذكر ميزة الخيارات الأخرى ، مثل SET_NULL أو SET_DEFAULT أو حتى DO_NOTHING. بشكل أساسي ، من وجهة نظر الإدارة ، تريد "حذف" تلك السجلات. لكنك لا تريدهم أن يختفوا. لأسباب عدة. ربما حذفها شخص ما عن طريق الخطأ أو للتدقيق والمراقبة. والإبلاغ عادي. لذلك يمكن أن يكون وسيلة "لفصل" العقار عن المدينة. مرة أخرى ، سوف يعتمد على كيفية كتابة طلبك.
على سبيل المثال ، تحتوي بعض التطبيقات على حقل "تم حذفه" وهو 0 أو 1. وكل عمليات البحث الخاصة بهم وطرق عرض القائمة ، إلخ ، أي شيء يمكن أن يظهر في التقارير أو في أي مكان يمكن للمستخدم الوصول إليه من الواجهة الأمامية ، استبعاد أي شيء تم
deleted == 1
.
ومع ذلك ، إذا قمت بإنشاء تقرير مخصص أو استعلام مخصص لسحب قائمة السجلات التي تم حذفها وحتى أكثر لمعرفة متى تم تعديله آخر مرة (حقل آخر) ومن قبل (أي من قام بحذفه ومتى) .. هذا مفيد جدا من الناحية التنفيذية.
ولا تنسَ أنه يمكنك التراجع عن عمليات الحذف العرضي بنفس البساطة
deleted = 0
لتلك السجلات.
وجهة نظري هو ، إذا كان هناك وظيفة ، هناك دائما سبب وراء ذلك. ليس دائما سبب وجيه. لكن السبب. وغالبا ما يكون جيدا جدا.
هذا هو السلوك المتبع عند حذف الكائن المشار إليه . أنها ليست محددة ل django ، وهذا هو معيار SQL.
هناك 6 إجراءات محتملة يجب اتخاذها عند حدوث هذا الحدث:
-
CASCADE
: عند حذف الكائن المشار إليه ، قم أيضًا بحذف الكائنات التي تحتوي على مراجع إليه (عند إزالة منشور مدونة على سبيل المثال ، قد ترغب في حذف التعليقات أيضًا). مكافئ SQL:CASCADE
. -
PROTECT
: لا تسمح بحذف الكائن المشار إليه. لحذفها ، يجب عليك حذف جميع الكائنات التي تشير إليها يدويًا. مكافئ SQL:RESTRICT
. -
SET_NULL
: تعيين المرجع إلى NULL (يتطلب الحقل أن يكون nullable). على سبيل المثال ، عندما تقوم بحذف مستخدم ، قد ترغب في الاحتفاظ بالتعليقات التي نشرها على مشاركات المدونة ، لكنك تقول إنه تم نشرها بواسطة مستخدم مجهول (أو محذوف). مكافئ SQL:SET NULL
. -
SET_DEFAULT
:SET_DEFAULT
القيمة الافتراضية. مكافئ SQL:SET DEFAULT
. -
SET(...)
: تعيين قيمة معينة. هذا ليس جزءًا من معيار SQL ويتم معالجته بالكامل بواسطة Django. -
DO_NOTHING
: من المحتمل أن تكون فكرة سيئة للغاية لأن هذا سيؤدي إلى حدوث مشكلات تكامل في قاعدة البيانات الخاصة بك (الرجوع إلى كائن غير موجود بالفعل). مكافئ SQL:NO ACTION
.
المصدر: وثائق جانغو
انظر أيضا وثائق PostGreSQL على سبيل المثال.
في معظم الحالات ، يكون
CASCADE
هو السلوك المتوقع ، ولكن بالنسبة لكل ForeignKey ، يجب عليك دائمًا أن تسأل نفسك ما هو السلوك المتوقع في هذه الحالة.
غالبًا ما يكون كل من
PROTECT
و
SET_NULL
مفيدًا.
يمكن أن يؤدي تعيين
CASCADE
عدم حذف كل قاعدة البيانات الخاصة بك في تتالي ، وذلك ببساطة عن طريق حذف مستخدم واحد.
يتم استخدام طريقة
on_delete
لإعلام Django بما يجب القيام به مع مثيلات النماذج التي تعتمد على مثيل الطراز الذي قمت بحذفه.
(على سبيل المثال علاقة
ForeignKey
).
يخبر
on_delete=models.CASCADE
Django
on_delete=models.CASCADE
تأثير الحذف ، أي الاستمرار في حذف النماذج التابعة أيضًا.
هنا مثال أكثر واقعية.
افترض أن لديك نموذج
Author
يمثل
ForeignKey
في نموذج
Book
.
الآن ، إذا قمت بحذف مثيل لنموذج
Author
، فلن يعرف Django ما يجب عمله مع مثيلات نموذج
Book
التي تعتمد على مثيل نموذج
Author
.
on_delete
طريقة
on_delete
Django بما يجب القيام به في هذه الحالة.
يؤدي إعداد
on_delete=models.CASCADE
إلى
on_delete=models.CASCADE
تعليمات إلى Django
on_delete=models.CASCADE
تأثير الحذف ، أي حذف جميع مثيلات طراز
Book
التي تعتمد على مثيل نموذج
Author
الذي قمت بحذفه.
ملاحظة: سوف يصبح
on_delete
وسيطة مطلوبة في Django 2.0.
في الإصدارات الأقدم ، يتم تعيين الإعدادات الافتراضية على
CASCADE
.
فيما يلي إجابة لسؤالك توضح: لماذا نستخدم on_delete؟
عند حذف كائن تمت الإشارة إليه بواسطة ForeignKey ، يحاكي Django بشكل افتراضي سلوك قيد SQL في DELETE CASCADE ويحذف أيضًا الكائن الذي يحتوي على ForeignKey. يمكن تجاوز هذا السلوك عن طريق تحديد وسيطة on_delete. على سبيل المثال ، إذا كان لديك ForeignKey nullable وتريد تعيينه فارغًا عند حذف الكائن المشار إليه:
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)
تم العثور على القيم المحتملة لـ on_delete في django.db.models:
تتالي: تتالي يحذف؛ الافتراضي.
حماية: منع حذف الكائن المشار إليه عن طريق رفع ProtectedError ، فئة فرعية من django.db.IntegrityError.
SET_NULL: تعيين ForeignKey فارغة. هذا ممكن فقط إذا كانت null صحيحة.
SET_DEFAULT: تعيين ForeignKey إلى القيمة الافتراضية الخاصة به؛ يجب تعيين افتراضي لـ ForeignKey.