禁止使用save()以防止由于未保存的相关对象而导致数据丢失 [英] save() prohibited to prevent data loss due to unsaved related object

查看:522
本文介绍了禁止使用save()以防止由于未保存的相关对象而导致数据丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将新创建的 ModelForm 的主键传递给同一视图中的另一个表单字段,但是出现错误。有什么建议可以使这项工作吗?
就像过去一样,这就是答案:

I need to pass a primary key from a newly created ModelForm to another form field in the same view but I get an error. Any suggestions to make this work? It looks like in the past, this would be the answer:

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

From the documentation, this is what is happening in the newer Django version > 1.8.3


p3 = Place(name ='Demon Dogs',address ='944 W.Fullerton ')
Restaurant.objects.create(place = p3,serves_hot_dogs = True,serves_pizza = False)

追溯(最近一次通话):

... < br>
ValueError:禁止使用save()防止由于未保存的相关对象位置而导致数据丢失。

p3 = Place(name='Demon Dogs', address='944 W. Fullerton') Restaurant.objects.create(place=p3, serves_hot_dogs=True, serves_pizza=False)
Traceback (most recent call last):
...
ValueError: save() prohibited to prevent data loss due to unsaved related object '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')


推荐答案

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

This was introduced in Django 1.8. Previously you could assign not saved instance to One-To-One relation and in case of fail it was silently skipped. Starting from Django 1.8 you will get error message in this case. Check a documentation of Django 1.7 -> 1.8 upgrade.

它说:


将未保存的对象分配给ForeignKey,GenericForeignKey和
OneToOneField现在会引发ValueError。

Assigning unsaved objects to a ForeignKey, GenericForeignKey, and OneToOneField now raises a ValueError.

如果对更多详细信息感兴趣,可以在 django.db.models.base 中检查保存方法: :

If you are interested in more details, you can check save method in django.db.models.base: Some part of it:

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 == None ValueError 将被筹集。

Last 5 rows are where this error is raised. basically your related obj which is not saved will have obj.pk == None and ValueError will be raised.

这篇关于禁止使用save()以防止由于未保存的相关对象而导致数据丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆