django的Form类是否保持状态?

sly*_*ete 0 python django

我正在用django构建我的第一个表单,我看到了一些我根本没想到的行为.我定义了一个表单类:

class AssignmentFilterForm(forms.Form):
filters = []
filter = forms.ChoiceField()

def __init__(self, *args, **kwargs):
    super(forms.Form, self).__init__(*args, **kwargs)
    self.filters.append(PatientFilter('All'))
    self.filters.append(PatientFilter('Assigned', 'service__isnull', False))
    self.filters.append(PatientFilter('Unassigned', 'service__isnull', True))

    for i, f in enumerate(self.filters):
        self.fields["filter"].choices.append((i, f.name))
Run Code Online (Sandbox Code Playgroud)

当我使用以下方法将此表单输出到模板时:

{{ form.as_p }}
Run Code Online (Sandbox Code Playgroud)

我看到了正确的选择.但是,刷新页面后,我在选择框中看到列表三次.再次点击刷新会导致列表在选择框中显示10次!

这是我的观点:

@login_required
def assign_test(request):
pg = PhysicianGroup.objects.get(pk=physician_group)

if request.method == 'POST':
    form = AssignmentFilterForm(request.POST)
    if form.is_valid():
        yes = False
else:
    form = AssignmentFilterForm()
    patients = pg.allPatients().order_by('bed__room__unit', 'bed__room__order', 'bed__order' )

return render_to_response('hospitalists/assign_test.html', RequestContext(request,  {'patients': patients, 'form': form,}))
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

谢谢,皮特

spb*_*gie 7

这实际上是Python的一个功能,它吸引了很多人.

当你在类上定义变量filters = []时,在最初定义类时会计算表达式的右半部分.因此,当您的代码首次运行时,它将在内存中创建一个新列表并返回对此列表的引用.因此,每个AssignmentFilterForm实例都有自己的过滤器变量,但它们都将指向内存中的相同列表.要解决此问题,只需将初始化移动self.filters到您的__init__方法中即可.

大多数情况下,您不会遇到此问题,因为您使用的类型不会存储为引用.数字,布尔值等存储为其值.字符串通过引用存储,但字符串是不可变的,这意味着每次更改字符串并返回新引用时,必须在内存中创建新字符串.

指针通常不会出现在脚本语言中,所以一开始它们常常会让人感到困惑.

这是一个简单的IDLE会话示例,用于显示正在发生的事情

>>> class Test():
    myList = []
    def __init__( self ):
        self.myList.append( "a" )


>>> Test.myList
[]
>>> test1 = Test()
>>> Test.myList
['a']
>>> test1.myList
['a']
>>> test2 = Test()
>>> test2.myList
['a', 'a']
>>> test1.myList
['a', 'a']
>>> Test.myList
['a', 'a']
Run Code Online (Sandbox Code Playgroud)