这是我的场景:我在页面上有多个选择框,用户从ModelChoiceField中选择选项,并重定向到一个视图,其中选定的选项作为参数传递。类似的东西:
class BrowseForm(forms.Form):
thing = forms.ModelChoiceField(queryset=Thing.objects.all(), empty_label=None, widget=forms.Select(attrs={'onchange': 'this.form.submit();'}))
stuff = forms.ModelChoiceField(queryset=Stuff.objects.all(), empty_label=None, widget=forms.Select(attrs={'onchange': 'this.form.submit();'}))
视图:
def browse(request):
thing_list = Thing.objects.all()
if request.method == 'POST':
form = BrowseForm(request.POST)
if form.is_valid():
thing = form.cleaned_data['thing']
stuff = form.cleaned_data['stuff']
return HttpResponseRedirect(reverse('browse_thing', kwargs={'thing':thing, 'stuff':stuff}))
else:
form = BrowseForm()
return render(request, 'browse.html', {'form':form, 'thing_list':thing_list})
这要求我提交BrowseForm
的两个字段,但我希望thing
和stuff
有两个不同的网址,其中thing
或{{ 1}}作为参数传递,而不是两者。类似的东西:
stuff
有没有办法用一个表单和一个视图执行此操作?或者我是否需要为url(r'^browse/things/(?P<thing>[\w-]+)/$', 'views.browse', name='browse_thing'),
url(r'^browse/stuff/(?P<stuff>[\w-]+)/$', 'views.browse', name='browse_stuff'),
和thing
编写不同的表单,然后检查在我的视图中传递哪个表单并相应地重定向到相应的URL?你会怎么做?谢谢你的想法!
答案 0 :(得分:0)
您可以选择根据是否传入thing
或stuff
来显示各种元素,因此您的视图会显示:
def browse(request, thing=None, stuff=None):
# your code, then...
return render(request, 'browse.html', {
'form': form,
'thing_list': thing_list,
'stuff_list': stuff_list,
'has_thing': bool(thing),
'has_stuff': bool(stuff)
})
然后在您的模板中,您可以执行以下操作:
{% for f in form %}
{% if f.name == 'thing' and has_thing %}
<!-- render it -->
{% endif %}
{% if f.name == 'stuff' and has_stuff %}
<!-- render it -->
{% endif %}
{% endfor %}
另请注意在required=False
字段中设置BrowseForm
,这样就不会在POST
上收到验证错误,因为您只有一个或另一个。
答案 1 :(得分:0)
虽然看起来不是很干,但这就是我解决问题的方法:
forms.py:
class StuffBrowseForm(forms.Form):
stuff = forms.ModelChoiceField(queryset=Stuff.objects.all(), widget=forms.Select(attrs={'onchange': 'this.form.submit();'}))
class ThingBrowseForm(forms.Form):
thing = forms.ModelChoiceField(queryset=Thing.objects.all(), widget=forms.Select(attrs={'onchange': 'this.form.submit();'}))
视图:
def browse(request):
thing_list = Thing.objects.all()
if request.method == 'POST':
form1 = StuffBrowseForm(request.POST)
form2 = ThingBrowseForm(request.POST)
if form1.is_valid():
stuff = form1.cleaned_data['stuff']
return HttpResponseRedirect(reverse('browse_stuffs', kwargs={'stuff':stuff}))
elif form2.is_valid():
thing = form2.cleaned_data['thing']
return HttpResponseRedirect(reverse('browse_things', kwargs={'thing':thing}))
else:
form1 = StuffBrowseForm()
form2 = ThingBrowseForm()
return render(request, 'browse.html', {'form1':form1, 'form2':form2, 'thing_list':thing_list})
网址:
url(r'^browse/$', 'views.browse', name='browse'),
url(r'^browse/stuff/(?P<stuff>[\w-]+)/$', 'views.browse_stuffs', name='browse_stuffs'),
url(r'^browse/things/(?P<thing>[\w-]+)/$', 'views.browse_things', name='browse_things'),