Save() запрещено для предотвращения потери данных из-за несохраненного связанного объекта
Мне нужно передать первичный ключ из вновь созданного ModelForm
в другое поле формы в том же представлении, но я получаю сообщение об ошибке. Любые предложения, чтобы сделать эту работу?
Похоже, в прошлом это было бы ответом:
def contact_create(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse(contact_details, args=(form.pk,)))
else:
form = ContactForm()
Из документации это то, что происходит в новой версии Django > 1.8.3
p3 = Место (name= "Демонские собаки", адрес = '944 W. Fullerton') Restaurant.objects.create(place = p3, serve_hot_dogs = True, serve_pizza = False)
Traceback (последний последний звонок):
...
ValueError: save() запрещено для предотвращения потери данных из-за несохраненного связанного объекта "место".
Вот как я получаю свой pk
из представления:
my_id = ""
if form.is_valid():
# deal with form first to get id
model_instance = form.save(commit=False)
model_instance.pub_date= timezone.now()
model_instance.user= current_user.id
model_instance.save()
my_id = model_instance.pk
if hourformset.is_valid():
hourformset.save(commit=False)
for product in hourformset:
if product.is_valid():
product.save(commit=False)
product.company = my_id
product.save()
else:
print(" modelform not saved")
return HttpResponseRedirect('/bizprofile/success')
Ответы
Ответ 1
Это было введено в Django 1.8. Раньше вы могли назначить не сохраненный экземпляр отношения "один-к-одному", а в случае неудачи он пропустил молча. Начиная с Django 1.8, в этом случае вы получите сообщение об ошибке.
Проверьте документацию в версии Django 1.7 → 1.8.
В нем говорится:
Назначение несохраненных объектов для ForeignKey, GenericForeignKey и OneToOneField теперь вызывает ValueError.
Если вас интересует более подробная информация, вы можете проверить метод save
в django.db.models.base
: Часть его:
for field in self._meta.concrete_fields:
if field.is_relation:
# If the related field isn't cached, then an instance hasn't
# been assigned and there no need to worry about this check.
try:
getattr(self, field.get_cache_name())
except AttributeError:
continue
obj = getattr(self, field.name, None)
# A pk may have been assigned manually to a model instance not
# saved to the database (or auto-generated in a case like
# UUIDField), but we allow the save to proceed and rely on the
# database to raise an IntegrityError if applicable. If
# constraints aren't supported by the database, there the
# unavoidable risk of data corruption.
if obj and obj.pk is None:
raise ValueError(
"save() prohibited to prevent data loss due to "
"unsaved related object '%s'." % field.name
)
Последние 5 строк, где эта ошибка возникает. в основном ваш связанный obj
, который не сохраняется, будет иметь значение obj.pk == None
и ValueError
.
Ответ 2
это просто:
p3 = Place(name='Demon Dogs', address='944 W. Fullerton')
p3.save() # <--- you need to save the instance first, and then assign
Restaurant.objects.create(
place=p3, serves_hot_dogs=True, serves_pizza=False
)
Ответ 3
Ответ. Проблема возникла из django, не сохраняющего пустые или неизменные формы. Это привело к нулевым полям для этих несохраненных форм. Проблема была устранена путем разрешения пустых полей на внешних ключах, по сути, - всех полей. Таким образом, пустые или неизменные формы не возвращали никаких ошибок при сохранении.
FYI: Обратитесь к ответу @wolendranh.