过滤器导致django的下拉列表

时间:2014-11-10 20:23:26

标签: python django

我想在我的django页面上找到一个基本的下拉框和一个提交按钮。当用户从下拉列表中选择某些内容并点击提交时,它会过滤结果。这应该很简单,但我花了几个小时,却找不到我想要做的例子。如何从POST获取数据?许多人建议不要使用原始POST数据并使用form.is_valid(),但是在这种情况下我没有使用forms.py(不确定我需要使用forms.py来使用form.is_valid ?? Even如果我可以使用forms.is_valid如何提取用户选择的内容?)。

这是我的views.py

def dashboard(request):
    plants = Plant.objects.all().order_by('IMS_plant')

    if request.POST:
        #selectedplant = #need to figure out how to get the value from the form in the template
        sightings = Sighting.objects.all().filter(IMS_plant=selectedplant)
        context =  {'sightings':sightings, 'plants': plants}
    else:
        sightings = Sighting.objects.all().order_by('date')    
        context =  {'sightings':sightings, 'plants': plants}

    return render_to_response('dashboard.html', context, context_instance=RequestContext(request))

这是我的模板

<form action="/dashboard/" method="post">
  {% csrf_token %}
  <select name="plant">
    <option selected="selected">All Plants</option>
    {% for plant in plants %}
    <option value="{{ plant.IMS_plant }}">{{ plant.IMS_plant }}</option>
    {% endfor %}
  </select>
  <input type="submit" value="Select Plant">
</form>
<p>
  {% for sighting in sightings %}
  <a href="/dashboard/sighting/{{ sighting.slug }}/ ">{{ sighting.date|date:"m/d/Y" }} {{ sighting.brand }} ${{ sighting.price|intcomma }} </a>
  <br>{% endfor %}

3 个答案:

答案 0 :(得分:4)

使用django-way。使用表格。

forms.py:

class FilterForm(forms.Form):
    selectedplant = forms.ModelChoiceField(queryset=Plant.objects.all().order_by('IMS_plant'), required=True)

view.py:

def dashboard(request):
    form = FilterForm()
    sightings = []
    if request.POST:
        form = FilterForm(request.POST)
        if form.is_valid():
            selectedplant = form.cleaned_data['selectedplant']
            sightings = Sighting.objects.filter(IMS_plant=selectedplant)
        else:
            sightings = Sighting.objects.all().order_by('date')  
    else:
        sightings = Sighting.objects.all().order_by('date')    

    context =  {'sightings':sightings, 'form': form}

    return render_to_response('dashboard.html', context, context_instance=RequestContext(request))

然后只需在模板中呈现{{form}}

答案 1 :(得分:1)

我稍微调整了EvilX的解决方案,以便有一个“全部显示”的选项。

forms.py

class FilterForm(forms.Form):
    selectedplant = forms.ModelChoiceField(queryset=Plant.objects.all().order_by('IMS_plant'), required=False, label='', empty_label="Show All")

views.py

def dashboard(request):
    form = FilterForm()
    sightings = []
    if request.POST:
        form = FilterForm(request.POST)
        if form.is_valid():
            selectedplant = form.cleaned_data['selectedplant']
            if selectedplant == None:
                sightings = Sighting.objects.all().order_by('date')
            else:
                sightings = Sighting.objects.filter(IMS_plant=selectedplant)            
        else:
            sightings = Sighting.objects.all().order_by('date')  
    else:
        sightings = Sighting.objects.all().order_by('date')    

    context =  {'sightings': sightings, 'form': form}

    return render_to_response('dashboard.html', context, context_instance=RequestContext(request))

这很有效,虽然我对sightings = Sighting.objects.all().order_by('date')在代码中出现3次这一事实并不感到兴奋,但它并不是世界末日(只是希望它看起来更清洁一点)。 / p>

再次感谢EvilX!

答案 2 :(得分:-1)

Django-filter应用程序完全符合您的要求。如果您对实现比对该功能更感兴趣,那么查看source code应该是有益的。