我正在用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)
我究竟做错了什么?
谢谢,皮特
这实际上是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)
| 归档时间: |
|
| 查看次数: |
588 次 |
| 最近记录: |