django 动态过滤表单
我正在把一个项目从php转换成Django,遇到了过滤菜单的问题。我有一个表单:
class SearchForm(forms.Form):
genus = forms.CharField(max_length=100)
# species
species = forms.CharField(max_length=100)
# island group
island_group = forms.ModelChoiceField(queryset=Localitymayor.objects.values_list('islandgroup', flat=True).distinct('islandgroup').exclude(islandgroup="n/a").order_by('islandgroup'), empty_label=_("Not Specified"))
# island name
island_name = forms.ModelChoiceField(queryset=Localitymayor.objects.values_list('islandname', flat=True).distinct('islandname').exclude(islandname="n/a").order_by('islandname'), empty_label=_("Not Specified"))
我的模板大致是这样的:
<form action="{% url cdrs_search %}" method="post">{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
</div>
{% endfor %}
</form>
现在我想根据选择的 island_group
来过滤 island_name
的输出。在我的php项目中,我是通过ajax的onChange调用另一个php脚本来实现的。不过,现在在Django中我有点迷茫,不知道该怎么做。因为这是我第一次在Django中使用ajax,所以如果有人能给我一些建议,告诉我处理这个简单但常见的过滤菜单问题的最佳方法,我会非常感激。提前谢谢大家。
3 个回答
1
你需要有一个页面,让你的ajax脚本可以发送请求,去获取一个根据某个组别的名字列表,比如:
# views.py
def ajax_endpoint(request):
# leaving error checking to you
group = request.GET.get('group')
names_list = avalable_names(group) # some function or db call
return HttpResponse(json.dumps(names_list))
1
一种选择是用JavaScript来实现这个功能。你可以通过jQuery发起一个ajax请求,去调用一个单独的视图。这个单独的视图的工作是根据用户选择的岛屿组(island_group)来处理服务器端的数据排序(比如岛屿的名字)。然后,你可以用JavaScript把从视图返回的结果填充到你的表单中。有一些很好的例子可以帮助你理解怎么做,可以在这个博客里找到(内容有点多,但很有用),还有这篇关于如何用JavaScript实现的文章,以及这个教程(非常推荐)。
还有一个很好的Stack Overflow帖子,解释了为什么必须这样做,虽然可能有点啰嗦,但在我创建过滤表单时,这个帖子帮我理清了思路。你可以看看这个问题的被接受的答案。
0
这里是来自betspire.com的票务表单代码的修改版本。这个代码片段需要先加载jQuery库。
你需要的JavaScript代码如下:
function update_select(select, data) {
select.find('option').remove();
select.append($('<option value="">-------</option>'));
for (var i in data) {
select.append($('<option value="'+data[i][0]+'">'+data[i][1]+'</option>'));
}
}
$('select[name=island_group]').live('change', function(e) {
$.get(
'{% url island_name_choices_for_island_group %}',
{
'island_group': $(this).val(),
},
function(data, textStatus, jqXHR) {
update_select($('select[name=island_name]'), data);
},
'json'
);
});
添加到网址:
url(
r'island_name/choices/$',
'island_name_choices_for_island_group', {
}, 'island_name_choices_for_island_group',
),
添加到视图:
from django.utils import simplejson
from models import *
def island_name_choices_for_island_group(request, qs=None):
if qs is None:
# Change the default QS to your needs
# (you didn't specify it)
qs = Island.objects.all()
if request.GET.get('island_group'):
# assuming your Island model has an FK named island_group to model IslandGroup
qs = qs.filter(island_group__pk=request.GET.get('island_group'))
results = []
for choice in qs:
results.append((choice.pk, choice.name))
return http.HttpResponse(simplejson.dumps(results))
如果你遇到任何问题,请告诉我。