Зачем мне сохранять эту модель перед добавлением в другую?

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

  •  05-07-2019
  •  | 
  •  

Вопрос

В 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 () , он должен иметь возможность создать продукт then (и сгенерировать идентификатор).

Я могу обойти эту проблему, используя этот код в блоке кроме :

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 () установит идентификатор объекта, если он должен его создать.

Кроме того, если вы не возражаете против пустых отношений FK в таблице Article, вы можете добавить 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 не присваивает ему идентификатор, пока он не будет сохранен. Технически вы можете вручную назначить ему идентификатор и избежать этой проблемы. Кажется, вы позволяете Django обрабатывать то, что вполне приемлемо.

У Джанго проблемы с M2M. Зачем? Если у ModelB еще нет идентификатора, что будет в столбце model_b_id в таблице M2M? Ошибка для нулевого product_id , скорее всего, является ошибкой нулевого ограничения для поля M2M, а не для идентификатора записи ModelB.

Если вы хотите, чтобы они "преуспели вместе" или "потерпеть неудачу вместе" возможно, пришло время заняться транзакциями. Вы, например, заключаете все это в транзакцию и выполняете откат в случае частичного сбоя. Я не проделал большую работу лично в этой области, так что, надеюсь, кто-то еще поможет в этой теме.

Нет смысла включать фрагмент кода в транзакции, так как вы должны прочитать Документация Django , чтобы получить хорошее понимание.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top