Django表单与过滤

0 投票
2 回答
931 浏览
提问于 2025-04-16 18:02

我有一个工作选择表单,用户可以通过这个表单来:

1) 选择一组单选按钮来过滤。这让用户可以选择想用什么方法来过滤列表。(这会发送一个GET请求,带上'filterBy'这个查询参数)

2) 让用户通过一个下拉框来过滤列表,这个下拉框的内容是根据第1步的选择生成的。这个表单会发送一个POST请求,'filter'参数的值是所选过滤对象的主键(pk)

这是我写的代码:

selectForm = JobSelectForm()
filterByForm = FilterByForm()
filterForm = FilterForm()

if request.method == 'POST':
    #this works just fine
    if 'job' in request.POST:
        return HttpResponseRedirect("/portal/jobs/%s/"%(request.POST['job']))

    if 'filter' in request.POST:
        filterForm = FilterForm(initial = {'filter': request.POST['filter']})

        ###### The Problem is below here
        ###### I cant get the 'filterBy' query string 
        ###### because this is a POST and not a GET
        ###### Is there a better way to write this filtering?

        if request.GET['filterby'] == 'G':
            obj = Group.objects.get(pk=request.POST['filter'])
            selectForm.fields['job'].queryset = Job.objects.filter(group=obj).order_by('name')
        elif request.GET['filterby'] == 'H':
            obj = Host.objects.get(pk=request.POST['filter'])
            selectForm.fields['job'].queryset = Job.objects.filter(host=obj).order_by('name')
        elif request.GET['filterby'] == 'L':
            obj = Location.objects.get(pk=request.POST['filter'])
            selectForm.fields['job'].queryset = Job.objects.filter(colo=obj).order_by('name')

###### All of this works fine too
elif request.method == 'GET':
    if request.GET.has_key('filterby'):
        if request.GET['filterby']:
            filterByForm = FilterByForm(initial = {'filterby': request.GET['filterby']})
            if request.GET['filterby'] == 'G':
                filterForm.fields['filter'].queryset = Group.objects.all().order_by('name')
            elif request.GET['filterby'] == 'H':
                filterForm.fields['filter'].queryset = Host.objects.all().order_by('name')
            elif request.GET['filterby'] == 'L':
                filterForm.fields['filter'].queryset = Location.objects.all().order_by('name')

2 个回答

0

你应该把有问题的代码放在表单的重写的 __init__ 方法里。

1

使用 request.REQUEST(参考:Django 请求和响应对象)。它包含了 request.POSTrequest.GET 的所有值。

另外,在Python中使用字典时,你应该总是确认你要访问的键是否存在。可以通过两种方式来检查:

1) 明确地测试字典中是否有这个键

if request.GET.has_key('filterby') and request.GET['filterby'] == 'G':
    obj = Group.objects.get(pk=request.POST['filter'])
    selectForm.fields['job'].queryset = Job.objects.filter(group=obj).order_by('name')

2) 使用字典的 get 方法

if request.GET.get('filterby') == 'G':
    obj = Group.objects.get(pk=request.POST['filter'])
    selectForm.fields['job'].queryset = Job.objects.filter(group=obj).order_by('name')

使用 dict.get 时,你还可以传入一个默认值:

if request.GET.get('filterby', valueIfKeyDoesntExist) == 'G':
    obj = Group.objects.get(pk=request.POST['filter'])
    selectForm.fields['job'].queryset = Job.objects.filter(group=obj).order_by('name')

撰写回答