ListView和Form在同一视图上,使用表单过滤结果

时间:2015-01-22 21:03:59

标签: django

我是Django的新手,我在阅读完本教程之后一直试图制作如此小的应用程序,但我无法弄清楚我的代码有什么问题。

我尝试做的是使用ListView下面的表单(使用相同的视图)列出名为project的模型的所有数据库条目,用户可以使用它来过滤要显示的条目在文本字段中提交数据的方法。

我成功完成了这项工作,看起来像这样:

App

但是,一旦用户点击"过滤结果"按钮在文本字段上提供一些过滤模式(让我们说,按名称过滤=" PROJECT3"将其他字段留空),而不是使用过滤后的数据和下面的表单呈现页面,这是我的意图,它只是返回一个白页。

有人可以解释一下我的代码有什么问题吗?

以下是相关部分:

forms.py

class FilterForm(forms.Form):
    pjt_name = forms.CharField(label='Name', max_length=200, widget=forms.TextInput(attrs={'size':'20'}))
    pjt_status = forms.CharField(label='Status', max_length=20, widget=forms.TextInput(attrs={'size':'20'}) )
    pjt_priority = forms.CharField(label='Priority', max_length=20, widget=forms.TextInput(attrs={'size':'20'}))
    pjt_internal_sponsor = forms.CharField(label='Int Sponsor', max_length=20, widget=forms.TextInput(attrs={'size':'20'}))
    pjt_external_sponsor = forms.CharField(label='Ext Sponsor', max_length=20, widget=forms.TextInput(attrs={'size':'20'}))

views.py

from App.models import Project
from django.views.generic import ListView
from django.shortcuts import render
from django.template import RequestContext
from App.forms import FilterForm

class ProjectListView(ListView):

    context_object_name = 'project_list'
    template_name='App/index.html'

    def get_context_data(self, **kwargs):
            context = super(ProjectListView, self).get_context_data(**kwargs)
            if 'filter_form' not in context:
                    context['filter_form'] = FilterForm()
            return context

    def get_queryset(self):
            form = FilterForm(self.request.GET)
            if form.is_valid():
                    name = form.cleaned_data['pjt_name']
                    i_sp = form.cleaned_data['pjt_internal_sponsor']
                    e_sp = form.cleaned_data['pjt_external_sponsor']
                    status = form.cleaned_data['pjt_status']
                    pri = form.cleaned_data['pjt_priority']
                    return send_filtered_results(name, i_sp, e_sp, status, pri)
            else:
                    return Project.objects.order_by('-project_creation_date')[:5]

    def send_filtered_results(name, i_sp, e_sp, status, pri):
            return  Project.objects.filter(project_name__in=name,internal_sponsor_name__in=i_sp, external_sponsor_name__in=e_sp, project_status__in=status, project_priority__in=pri).exclude(alias__isnull=True).exclude(alias__exact='')

urls.py

from django.conf.urls import patterns, url
from App.views import ProjectListView
from django.views.generic import DetailView
from App.models import Project, Task

urlpatterns = patterns('',
    url(r'^$',
            ProjectListView.as_view())

2 个答案:

答案 0 :(得分:1)

您的代码很混乱,Project.objects.filter(...)远非侵略性。它只是没有返回任何对象。

不要使用name__in=namename__contains=name

答案 1 :(得分:1)

答案在您的回复/状态代码中:

  

完成后,我得到一个白页,runserver返回[23 / Jan / 2015 00:21:09]" POST / App / HTTP / 1.1" 405 0

您正在发布到没有POST处理程序的视图。 你应该收到错误的说法,但405表示不允许这样做。

post添加CBV方法。基于Django类的视图将请求方法映射到函数,因此GET通过CBV.get处理,POST通过CBV.post处理

出于演示目的,请添加:

# essentially, mirror get behavior exactly on POST
def post(self, *args, **kwargs):
    return self.get(*args, **kwargs)

将表单处理程序更改为从request.POST而不是request.GET

        form = FilterForm(self.request.POST)

我建议您开始使用print()log开始查看发生了什么。 request.GET应为空,因为..您没有使用GET参数。该数据将位于request.POST