在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文档以获得良好的理解。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top