Подтвердить что ты не робот

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')
4b9b3361

Ответ 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.