0

ジャンゴでは、次のようなことをしようとしています:

# 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" の null 値が not-null 制約に違反しています

しかし、なぜこれが問題なのかわかりません。が呼び出されると、製品作成(および ID を生成)article.save()できるはずです。

exceptブロックで次のコードを使用することで、この問題を回避できます。

product = Component(name=product_name)
product.save()
article.product = product

しかし、これが私が懸念する理由は、article.save()失敗した場合、新しいコンポーネント/製品が既に作成されているためです。一緒に成功したり失敗したりしてほしい。

これを回避する良い方法はありますか?

4

3 に答える 3

4

Django ManyToManyField が機能する方法は、追加のテーブルを作成することです。ModelA と ModelB の 2 つのモデルがあるとします。もしそうなら...

ModelA.model_b = models.ManyToManyField(ModelB)

Django が実際に舞台裏で行っていることは、テーブルを作成することです... app_modela_modelb3 つの列: idmodel_a_idmodel_b_id

その思いを心に留めておいてください。ModelB の保存に関して、Django は保存されるまで ID を割り当てません。技術的には手動で ID を割り当てて、この問題を回避できます。完全に許容できるものをdjangoに処理させているようです。

Django で M2M を実行すると問題が発生します。なんで?ModelB がまだ ID を持っていない場合model_b_id、M2M テーブルの列には何が入りますか? null のエラーproduct_idは、ModelB レコード ID ではなく、M2M フィールドの null 制約エラーである可能性が高いです。

「一緒に成功したい」または「一緒に失敗したい」場合は、おそらくトランザクションを検討する時期です。たとえば、すべてをトランザクションにラップし、部分的な障害が発生した場合にロールバックを実行します。私はこの分野で個人的に多くの仕事をしたことがないので、他の誰かがそのトピックについて助けてくれることを願っています.

于 2009-11-27T05:45:32.830 に答える
1

Django のドキュメントを読んで理解を深める必要があるため、トランザクションにコード スニペットを含める価値はほとんどありません。

于 2009-11-27T10:58:51.043 に答える
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 に答える