Pregunta

En django, estoy tratando de hacer algo como esto:

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

Pero luego me dice:

  

valor nulo en la columna " product_id " viola la restricción no nula

Pero no entiendo por qué esto es un problema. Cuando se llama a article.save () , debe poder crear el producto luego (y generar una identificación).

Puedo solucionar este problema usando este código en el bloque excepto :

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

Pero la razón por la que esto me preocupa es porque si article.save () falla, ya habrá creado un nuevo componente / producto. Quiero que tengan éxito o fracasen juntos.

¿Hay una buena manera de evitar esto?

¿Fue útil?

Solución

Puede solucionar esto usando:

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

ya que estoy bastante seguro de que get_or_create () establecerá la identificación de un objeto, si tiene que crear uno.

Alternativamente, si no le importa tener relaciones FK vacías en la tabla Artículo, puede agregar null = True a la definición.

Otros consejos

La forma en que funciona Django ManyToManyField es que crea una tabla adicional. Digamos que tienes dos modelos, ModelA y ModelB. Si lo hiciste ...

ModelA.model_b = models.ManyToManyField(ModelB)

Lo que Django realmente hace detrás de escena es crear una tabla ... app_modela_modelb con tres columnas: id , model_a_id , model_b_id .

Mantenga ese pensamiento en su mente. Con respecto al guardado de ModelB, Django no le asigna una identificación hasta que se guarda. Técnicamente, podría asignarle manualmente una ID y evitar este problema. Parece que está dejando que django maneje lo que es perfectamente aceptable.

Django tiene un problema al hacer el M2M. ¿Por qué? Si ModelB todavía no tiene una identificación, ¿qué pasa en la columna model_b_id en la tabla M2M? El error para el product_id nulo es más que probable que sea un error de restricción nula en el campo M2M, no el ID de registro de ModelB.

Si desea que "tengan éxito juntos" o "fallar juntos" Quizás es hora de analizar las transacciones. Usted, por ejemplo, envuelve todo en una transacción y hace una reversión en caso de una falla parcial. No he hecho mucho trabajo personalmente en esta área, así que espero que alguien más sea de ayuda en ese tema.

Hay poco valor al incluir un fragmento de código en las transacciones, ya que debe leer la documentación de Django para obtener una buena comprensión.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top