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.





django-models