Django 表单如何获取先前实例的值?

0 投票
1 回答
507 浏览
提问于 2025-04-17 09:27

有没有人知道为什么会出现这种情况?

(Pdb) import copy

(Pdb) tmpForm=copy.copy(form1)
(Pdb) form1
<cms.forms.MainFeaturedForm object at 0x7f05a0493350>
(Pdb) tmpForm
<cms.forms.MainFeaturedForm object at 0x7f05a054e950>

我把form1复制到tmpForm(并确保它们在不同的内存地址上),这样可以确认这个行为不是因为form1被改变了。

(Pdb) v1=form1.save(commit=False)
(Pdb) v1.position

如上所示,在form1.save(commit=False)之后,v1.position的值是None。

(Pdb) v1.image_type=2
(Pdb) v1.Article=article
(Pdb) v1.section=33
(Pdb) v1.save()
(Pdb) v1.position
55L

在这里我设置了一些值并保存了它,save()函数把v1的位置改成了55(这是预期的结果)。

(Pdb) v2=tmpForm.save(commit=False)
(Pdb) v2.position
55L

但是现在,在我保存了v1之后,v2(一个全新的实例)的位置却被设置成了和v1相同的值(这不是我预期的结果)。


如果有帮助的话,这里是这个对象(类Featured)的save()函数:

def save(self):
    if self.Article:
        try:
            featured = Featured.objects.get(Article=self.Article, section=self.section)
            self.hiddenID = featured.hiddenID
            if self.position == None:
                if featured.position == None:
                    self.position = 55
                else:
                    self.position = featured.position

            super(Featured, self).save(force_insert=False, force_update=True)
        except Featured.DoesNotExist:
            self.hiddenID = None
            super(Featured, self).save(force_insert=True, force_update=False)
    else:
        self.hiddenID = None
        super(Featured, self).save(force_insert=True, force_update=False)

1 个回答

2

使用 copy.deepcopy() 而不是 copy.copy(我猜可能是因为它共享了数据字典的实例……)。

但是现在,在我保存了 v1 后,v2(一个完全新的实例)却被设置成了和 v1 一样的位置(这不是我预期的)。

这个说法是不对的。一个 modelform 实例在 init 中会设置 self.instance,然后只会在这个实例上进行操作。如果你复制了 form.instance 的引用,然后在表单外部修改它,当然会在 form.instance 上反映出来。

deepcopy 和 copy 的区别:

In [1]: import copy

In [2]: a={'foo':'bar'}

In [3]: b={'x': a}

In [4]: bb=copy.copy(b)

In [5]: b['x']['foo']
Out[5]: 'bar'

In [6]: b['x']['foo'] = 'test'

In [8]: bb['x']['foo']
Out[8]: 'test'

In [9]: bbb=copy.deepcopy(b)

In [10]: bbb['x']['foo'] = 'y'

In [11]: bb['x']['foo']
Out[11]: 'test'

In [12]: b['x']['foo']
Out[12]: 'test'

In [13]: bbb['x']['foo']
Out[13]: 'y'

问题在于,copy 只是复制一个值,并且它里面的引用会被保留。而 deepcopy() 则会复制一个值以及它里面所有的值。

撰写回答