在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)。
我可以在except
块中使用此代码解决此问题:
product = Component(name=product_name)
product.save()
article.product = product
但是我担心的原因是因为article.save()
失败,它已经创建了一个新的组件/产品。我希望他们一起成功或失败。
有一种很好的解决方法吗?
答案 0 :(得分:4)
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。
如果您希望他们“共同成功”或“一起失败”,或许是时候调查交易了。例如,您将整个事物包装在事务中,并在部分失败的情况下进行回滚。我没有亲自在这个领域做过很多工作,所以希望其他人能在这方面提供帮助。
答案 1 :(得分:1)
你可以通过使用:
解决这个问题target_product, created_flag = Component.objects.get_or_create(name=product_name)
article.product = target_product
因为我非常确定get_or_create()
会设置对象的ID,如果它必须创建一个。
或者,如果您不介意Article表上的空FK关系,则可以将null=True
添加到定义中。
答案 2 :(得分:1)
在交易中包含代码段几乎没有价值,因为您应该阅读the Django documentation以获得良好的理解。