0

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

有没有一个很好的方法来解决这个问题?

4

3 回答 3

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,那么model_b_idM2M 表的列中有什么内容?null 的错误product_id很可能是 M2M 字段上的 null 约束错误,而不是 ModelB 记录 ID。

如果您希望他们“一起成功”或“一起失败”,也许是时候研究交易了。例如,您将整个事物包装在事务中,并在部分失败的情况下进行回滚。我个人在这方面没有做过很多工作,所以希望其他人能在这个话题上提供帮助。

于 2009-11-27T05:45:32.830 回答
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到定义中。

于 2009-11-27T10:54:18.090 回答
1

在事务中包含代码片段没有什么价值,因为您应该阅读Django 文档以获得良好的理解。

于 2009-11-27T10:58:51.043 回答