为什么在将此模型添加到另一个模型之前需要保存?

时间:2009-11-27 05:34:58

标签: python django models

在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()失败,它已经创建了一个新的组件/产品。我希望他们一起成功或失败。

有一种很好的解决方法吗?

3 个答案:

答案 0 :(得分:4)

Django ManyToManyField的工作方式是创建一个额外的表。所以说你有两个模型,ModelA和ModelB。如果你做了......

ModelA.model_b = models.ManyToManyField(ModelB)

Django在幕后实际做的是创建一个包含三列的表格app_modela_modelbidmodel_a_idmodel_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以获得良好的理解。