当前位置: 首页 > 面试题库 >

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

江华容
2023-03-14
问题内容

我需要将新创建的主键传递给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 =地点(名称=``恶魔狗’‘,地址=‘944 W.富乐顿’)Restaurant.objects.create(地点=
p3,serve_hot_dogs = True,serves_pizza = False)追溯
(最近一次调用是最近的):

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

问题答案:

这是在Django 1.8中引入的。以前,您可以将未保存的实例分配给一对一关系,如果失败,该实例将被静默跳过。从Django
1.8开始,在这种情况下,您会收到错误消息。查看Django 1.7-> 1.8
upgrade的文档。

它说:

现在,将未保存的对象分配给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
            )

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



 类似资料: