我有一个包含两种形式的页面:SearchForm和QuickAddForm。在Django的同一页面上处理两个表单并不容易,我花了两三天的时间试图让它工作。我有几个单元测试,我一直在使用:测试每个表单以确保它显示在页面上,测试提交有效搜索到searchform返回正确的结果,以及三个测试用于quickadd表单测试1)提交有效字段会导致新的Entry保存到数据库; 2)保存条目后,表单重定向到同一页面; 3)成功消息显示在该页面上。例如:
def test_quick_add_form_saves_entry(self):
self.client.post('/editor/', {'quickadd_pre-hw' : 'كلمة'}, follow=True)
self.assertEqual(Entry.objects.count(), 1)
经过大量工作(并在本页的答案和评论中得到了很大帮助:[Proper way to handle multiple forms on one page in Django)。我终于使表单正常工作,以便提交的条目成功保存在数据库中,并在发布后重定向。耶!
除了......当我在浏览器中打开页面并尝试输入新条目时,很明显它没有做这样的事情。你填写表格并点击“保存”,然后......没有任何反应。页面不会重新加载,并且该条目不会添加到数据库中。但测试(如上所述)测试这些功能的测试正在通过。 (正是在这一点上,我添加了成功消息的测试,至少,它有正确的失败。)搜索表正在工作。
我不知道什么可能阻止quickadd表单运行。此外,当表单不起作用时,我不明白测试是如何通过的。发生了什么???
这是代码(Python3,Django1.8 - 为了清晰起见略微简化):
editor.html
<form id="id_searchform" role="form" method="POST" action="/editor/">
{% csrf_token %}
{{ searchform.as_p }}
<button type="submit" class="btn btn-primary btn-lg"
name="{{searchform.prefix}}">Search</button>
</form>
...
<h1>New entry</h1>
<form id="id_quick_add_form" method="POST" action='/editor/' class="post-form">
{% csrf_token %}
{{ quickaddform.as_p }}
<button type="submit" class="save btn btn-primary"
name='{{quickaddform.prefix}}'>Save</button>
</form>
views.py
def _get_form(request, formcls, prefix):
data = request.POST if prefix in next(iter(request.POST.keys())) else None
return formcls(data, prefix=prefix)
def editor_home_page(request):
if request.method == 'POST':
searchform = _get_form(request, SearchForm, 'searchform_pre')
quickaddform = _get_form(request, QuickAddForm, 'quickadd_pre')
if searchform.is_bound and searchform.is_valid():
query = searchform.cleaned_data['searchterm']
results = Entry.objects.filter(bare_hw__icontains=query)
return render(request, 'dict/editor.html', {
'query' : query,
'results' : results,
'searchform' : searchform,
'quickaddform' : quickaddform,
})
elif quickaddform.is_bound and quickaddform.is_valid():
hw = quickaddform.cleaned_data['hw']
e = Entry.objects.create(hw=hw)
messages.success(request, "Entry %s successfully created." % e.hw)
return redirect('/editor/', {
'searchform': SearchForm(prefix='searchform_pre'),
'quickaddform': QuickAddForm(prefix='quickadd_pre'),
})
else:
return render(request, 'dict/editor.html', {
'searchform': SearchForm(prefix='searchform_pre'),
'quickaddform': QuickAddForm(prefix='quickadd_pre')
})
else:
return render(request, 'dict/editor.html', {
'searchform': SearchForm(prefix='searchform_pre'),
'quickaddform': QuickAddForm(prefix='quickadd_pre')
})
forms.py
class SearchForm(Form):
searchterm = forms.CharField(
max_length=100,
widget=forms.TextInput(attrs={
'placeholder': 'English | العربية',
'class' : 'form-control input-lg',
}),
required=True)
class QuickAddForm(Form):
hw = forms.CharField(
max_length=100,
widget=forms.TextInput(attrs={
'placeholder': 'ex: مَضْروب',
'class' : 'form-control',
}),
required=True)