Question

Dans Django, j'essaie de faire quelque chose comme ceci:

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

Mais ensuite, il me dit:

  

Valeur nulle dans la colonne " ID_produit " viole la contrainte non nulle

Mais je ne comprends pas pourquoi c'est un problème. Lorsque article.save () est appelé, il devrait pouvoir créer le produit puis (et générer un identifiant).

Je peux contourner ce problème en utilisant ce code dans le bloc sauf :

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

Mais cela me préoccupe, c'est que si article.save () échoue, il aura déjà créé un nouveau composant / produit. Je veux qu’ils réussissent ou échouent ensemble.

Y a-t-il un bon moyen de contourner cela?

Était-ce utile?

La solution

Vous pouvez contourner ce problème en utilisant:

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

car je suis presque sûr que get_or_create () définira l'identifiant d'un objet s'il doit en créer un.

Sinon, si les relations FK vides de la table Article ne vous dérangent pas, vous pouvez ajouter null = True à la définition.

Autres conseils

Django ManyToManyField fonctionne comme s'il créait une table supplémentaire. Alors disons que vous avez deux modèles, ModelA et ModelB. Si vous avez fait ...

ModelA.model_b = models.ManyToManyField(ModelB)

En réalité, Django crée une table ... app_modela_modelb avec trois colonnes: id , model_a_id , model_b_id .

Gardez cette pensée dans votre esprit. En ce qui concerne l’enregistrement de ModelB, Django ne lui attribue pas d’ID jusqu’à ce qu’il soit enregistré. Vous pouvez techniquement lui attribuer manuellement un identifiant et éviter ce problème. Il semble que vous laissiez django gérer ce qui est parfaitement acceptable.

Django a un problème à faire le M2M. Pourquoi? Si ModelB n'a pas encore d'identifiant, que se passe-t-il dans la colonne model_b_id de la table M2M? L'erreur pour null product_id est très probablement une erreur de contrainte null sur le champ M2M, pas l'identifiant d'enregistrement ModelB.

Si vous souhaitez qu’ils " réussissent ensemble " ou "échouer ensemble" Peut-être qu'il est temps d'examiner les transactions. Par exemple, vous encapsulez le tout dans une transaction et effectuez une restauration en cas d'échec partiel. Je n'ai pas fait beaucoup de travail personnellement dans ce domaine, donc j'espère que quelqu'un d'autre pourra vous aider à ce sujet.

Il est inutile d'inclure un extrait de code dans les transactions, car vous devriez lire la documentation Django pour bien comprendre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top