Javascript django动态过滤形式

Javascript django动态过滤形式,javascript,python,django,forms,menu,Javascript,Python,Django,Forms,Menu,我正在将一个项目从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

我正在将一个项目从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>
{%csrf\u令牌%}
{%形式的字段为%}
{{field.errors}}
{{field.label_tag}}:{{{field}
{%endfor%}

现在,我想根据
孤岛组的选择过滤
孤岛名称的输出。在我的php项目中,我通过对另一个php脚本的ajax onChange调用来管理这一点。然而,我对如何在Django做到这一点有点迷茫。由于这是我第一次在Django中使用ajax,我希望您能就如何处理这个简单但常见的过滤菜单问题提供一些建议。提前感谢。

您需要有一个视图,以便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))

一种选择是在javascript中执行此操作。您可以使用来自的ajax请求调用单独的视图。此单独视图的任务是根据用户选择的孤岛(组)处理模型数据(孤岛)名称的服务器端排序。然后,您可以使用javascript使用来自视图的响应重新填充表单。可以找到一些关于如何实现这一点的好例子(有点密集,但非常有用)和(强烈推荐)


还有一个很好的SO帖子,解释了为什么有必要这样做,它可能有点迂腐,但它帮助我在创建过滤表单时澄清了一些事情。请看下面的问题解答。

这里是对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'
        );
    });
添加到视图:

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))

如果您遇到任何麻烦,请告诉我。

为什么在Django会有什么不同?您仍然需要一个ajaxonchange函数来调用服务器端视图。感谢您提供的宝贵信息。我会看看我是否能让它为我工作。嗨,我已经尝试了你的代码,做了一些修改,但我仍然无法让ajax更新菜单。具体来说,我不确定我的html。我可以把我的代码发给你看看吗?首先:ajax视图中是否有python错误(通过打开url或使用firebug来验证ajax视图)?第二:是否存在javascript错误(使用firebug)?第三:添加“console.log”语句或使用firebug调试javascript,并检查预期代码是否使用预期参数运行:)好的-我现在就可以使用了。虽然我仍然不清楚
qs=None
但是。你能解释一下为什么这是必要的吗?呵呵,我很高兴你这么问。两件事:0)最好允许覆盖视图的参数(您可以将同一个视图与另一个url中的另一个queryset一起使用),1)在导入视图时计算关键字参数值,因此如果设置qs=MyModel.objects。。。。那么它就不是线程安全的。它也适用于额外上下文之类的参数。正如您在guru James Bennett的代码中所看到的,对于线程安全来说,额外的上下文kwarg值是None而不是{}:
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))