لماذا أحتاج لإنقاذ هذا النموذج قبل إضافتها إلى واحد آخر؟

StackOverflow https://stackoverflow.com/questions/1806937

  •  05-07-2019
  •  | 
  •  

سؤال

في جانغو، أنا أحاول أن أفعل شيئا من هذا القبيل:

# if form is valid ...
article = form.save(commit=False)
article.author = req.user

product_name = form.cleaned_data['product_name']
try:
    article.product = Component.objects.get(name=product_name)
except:
    article.product = Component(name=product_name)

article.save()
# do some more form processing ...

ولكن بعد ذلك يقول لي:

<اقتباس فقرة>   

وقيمة خالية في عمود "PRODUCT_ID" تنتهك القيد لا الصفرية

ولكن أنا لا أفهم لماذا هذه مشكلة. عندما يتم استدعاء article.save()، ينبغي أن تكون قادرة على خلق المنتج <م> ثم (وإنشاء معرف).

ويمكنني الحصول تغلب على هذه المشكلة عن طريق استخدام هذا الرمز في كتلة except:

product = Component(name=product_name)
product.save()
article.product = product

ولكن السبب في هذا يقلقني هو أنه إذا فشل article.save()، سيكون بالفعل قد خلقت مكون جديد / المنتج. أريد لها أن تنجح أو تفشل معا.

هل هناك طريقة لطيفة للالتفاف على هذا؟

هل كانت مفيدة؟

المحلول

هل يمكن الحصول على حول هذا باستخدام:

target_product, created_flag = Component.objects.get_or_create(name=product_name)
article.product = target_product

وأنا متأكد سوف get_or_create() تعيين معرف كائن، إذا كان لديه لإنشاء واحد.

وبدلا من ذلك، إذا كنت لا تمانع في العلاقات FK فارغة على الطاولة المادة، يمكنك إضافة null=True إلى تعريف.

نصائح أخرى

والطريقة التي يعمل بها جانغو ManyToManyField هو أنه يخلق جدول إضافي. لذلك نقول لديك نموذجين، ModelA وModelB. إذا كنت فعلت ...

ModelA.model_b = models.ManyToManyField(ModelB)

وماذا جانغو في الواقع لا وراء الكواليس وذلك بإنشاء جدول ... app_modela_modelb مع ثلاثة أعمدة: id، model_a_id، model_b_id

وعقد هذا الفكر في عقلك. وفيما يتعلق إنقاذ ModelB، بفك لا عين له معرف حتى يتم حفظه. هل يمكن من الناحية الفنية يدويا تعيينه معرف وتجنب هذه المشكلة. يبدو أنك كنت السماح جانغو التعامل مع ما هو مقبول تماما.

وجانغو لديه مشكلة ثم القيام M2M. لماذا ا؟ إذا لم يكن لديك ModelB معرف بعد، ما يجري في العمود model_b_id على الطاولة M2M؟ الخطأ لproduct_id باطل هو أكثر من المحتمل خطأ القيد فارغة على مجال M2M، وليس ModelB سجل معرف.

إذا كنت ترغب لهم "ننجح معا" أو "الفشل معا" ربما حان الوقت للنظر في المعاملات. كنت، على سبيل المثال، والتفاف كل شيء في الصفقة، والقيام التراجع في حالة الفشل الجزئي. أنا لم تفعل الكثير كله من عمل شخصيا في هذا المجال لذلك نأمل شخص آخر سيكون المساعدة في هذا الموضوع.

وهناك قيمة تذكر في بما في ذلك التعليمات البرمجية المتكررة على المعاملات، كما يجب أن تقرأ <لأ href = "http://docs.djangoproject.com/en/dev/topics/db/transactions/" يختلط = "نوفولو noreferrer" > وثائق جانغو للحصول على فهم جيد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top