Warum brauche ich dieses Modell zu retten, bevor es zu einem anderen hinzuzufügen?

StackOverflow https://stackoverflow.com/questions/1806937

  •  05-07-2019
  •  | 
  •  

Frage

In django, ich versuche, so etwas zu tun:

# 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 ...

Aber dann sagt es mir:

  

Nullwert in der Spalte "product_id" verletzt nicht-NULL-Constraint

Aber ich verstehe nicht, warum das ein Problem ist. Wenn article.save() genannt wird, soll es in der Lage sein, die das Produkt erstellen und (und erzeugt eine id).

Ich kann mit diesem Code in dem except Block, um dieses Problem umgehen:

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

Aber der Grund, dies mich betrifft, denn wenn article.save() ausfällt, wird es bereits eine neue Komponente / Produkt erstellt haben. Ich möchte, dass sie gemeinsam erfolgreich zu sein oder nicht.

Gibt es eine schöne Möglichkeit, dies zu umgehen?

War es hilfreich?

Lösung

Sie können dieses Problem umgehen, indem Sie:

target_product, created_flag = Component.objects.get_or_create(name=product_name)
article.product = target_product

, wie ich bin mir ziemlich sicher, dass get_or_create() die ID eines Objekts festgelegt wird, wenn es zu erstellen hat.

Alternativ, wenn Sie nicht leer FK Beziehungen auf der Artikel-Tabelle nichts dagegen haben, Sie null=True die Definition hinzufügen könnten.

Andere Tipps

Die Art und Weise der Django ManyToManyField funktioniert, ist, dass es eine zusätzliche Tabelle erstellt. So sagen, Sie haben zwei Modelle, ModelA und Modell B. Wenn ja ...

ModelA.model_b = models.ManyToManyField(ModelB)

Was Django tatsächlich tut, hinter den Kulissen wird eine Tabelle erstellt, ... app_modela_modelb mit drei Spalten:. id, model_a_id, model_b_id

Halten Sie die in Ihrem Kopf gedacht. Im Hinblick auf die Einsparung von Modell B, ist Django nicht abtreten es sich um eine ID, bis sie gespeichert wird. Sie könnten technisch es manuell eine ID zuweisen und dieses Problem zu vermeiden. Es scheint, du laesst django damit umgehen, was durchaus akzeptabel ist.

Django hat ein Problem, dann die M2M tun. Warum? Wenn Modell B eine ID hat noch nicht, geht, was in der model_b_id Spalte auf der M2M-Tabelle? Der Fehler für null product_id ist mehr als wahrscheinlich, ein NULL-Constraint-Fehler auf dem M2M-Bereich, nicht das Modell B Datensatz-ID.

Wenn Sie möchten, dass zu „zusammen erfolgreich“ oder „nicht bestanden zusammen“ vielleicht ist es Zeit, in Transaktionen zu suchen. Sie, zum Beispiel, wickeln Sie das Ganze in einer Transaktion, und ein Rollback im Fall eines teilweisen Ausfalls tun. Ich habe nicht eine ganze Menge Arbeit persönlich in diesem Bereich getan, so hoffentlich jemand andere zu diesem Thema hilfreich sein wird.

Es gibt wenig Wert einen Code-Snippet auf Transaktionen im einschließlich, wie Sie die Django-Dokumentation ein gutes Verständnis zu gewinnen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top