为什么在将此模型添加到另一个模型之前需要保存?
题
在django,我正在尝试做这样的事情:
# 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()
时,它应该能够创建产品然后(并生成一个id)。
我可以通过在
块中使用此代码来解决这个问题:
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()
会设置一个对象的id,如果它必须创建一个。
或者,如果您不介意Article表上的空FK关系,可以将 null = True
添加到定义中。
其他提示
Django ManyToManyField的工作方式是创建一个额外的表。所以说你有两个模型,ModelA和ModelB。如果你做了......
ModelA.model_b = models.ManyToManyField(ModelB)
Django在幕后实际上做了什么,它创建了一个表... app_modela_modelb
,包含三列: id
, model_a_id
, model_b_id 代码>
坚持这个想法。关于ModelB的保存,Django在保存之前不会为其分配ID。您可以在技术上手动为其分配ID并避免此问题。看来你正在让django处理完全可以接受的事情。
Django在做M2M时遇到了问题。为什么?如果ModelB还没有id,M2M表上 model_b_id
列的内容是什么? null product_id
的错误很可能是M2M字段上的空约束错误,而不是ModelB记录ID。
如果您希望他们“一起成功”,或“一起失败”或或许是时候研究交易了。例如,您将整个事物包装在事务中,并在部分失败的情况下执行回滚。我没有亲自在这个领域做过很多工作,所以希望其他人能在这方面提供帮助。
在事务中包含代码片段没什么价值,因为你应该阅读 Django文档以获得良好的理解。