禁止save()以防止由于未保存的相关对象而导致数据丢失

Edw*_*ner 34 python django

我需要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()
Run Code Online (Sandbox Code Playgroud)

从文档中,这是较新的Django版本中发生的事情 > 1.8.3

p3 = Place(name ='Demon Dogs',address ='944 W. Fullerton')Restaurant.objects.create(place = p3,serve_hot_dogs = True,serve_pizza = False)
Traceback(最近一次调用最后一次):
...
ValueError :save()禁止防止因未保存的相关对象'place'而导致数据丢失.

这就是我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')
Run Code Online (Sandbox Code Playgroud)

wol*_*anh 19

这是在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's 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's 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
            )
Run Code Online (Sandbox Code Playgroud)

最后5行是引发此错误的位置.基本上你相关的obj未保存会obj.pk == NoneValueError将提高.

  • 如果我知道该对象在数据库中怎么办?为了说服 Django,我必须多走一趟吗? (4认同)
  • 如果我想删除这个对象怎么办?如果我需要它为“无”怎么办? (3认同)

don*_*yor 14

很简单:

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
) 
Run Code Online (Sandbox Code Playgroud)

  • 即使我正在保存 modelform 实例,我也收到相同的值错误。查看我的代码并告诉我为什么我会得到这个:save() 被禁止以防止由于未保存的相关对象“公司”而导致数据丢失。 (2认同)