You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中如何基于用户表单输入查询数据库并在新页展示结果?

解决表单提交后传递参数过滤查询集的问题

嘿,我来帮你搞定这个表单查询的问题!你的代码已经有了基础框架,主要需要解决表单数据传递到ListView以及一些小的拼写错误,下面一步步来:

第一步:修正代码里的拼写/引用错误

先把明显的错误改掉,不然运行肯定报错:

  1. views.py里的form_class = CrsAttForm应该改成form_class = AttendanceForm——因为你在forms.py里定义的表单类是AttendanceForm,这里引用错了
  2. urls.py里的name='memebrs_list'拼写错误,应该是name='members_list',和views.py里success_url的reverse_lazy('office:members_list')对应上

第二步:传递表单数据到ListView并过滤查询集

这里有两种常用的方法,根据你的需求选一种:

方法1:通过URL查询参数传递(直观,适合非敏感数据)

这种方法会把表单参数拼在结果页面的URL里,用户可以直接分享带过滤条件的链接。

修改FormView,在跳转时带上参数

更新views.py里的AttendanceForm类,重写get_success_url方法,把表单的清洗后数据拼到URL上:

class AttendanceForm(generic.FormView):
    form_class = AttendanceForm  # 已经修正的类名
    template_name = 'office/crsatt_form.html'

    def get_success_url(self):
        # 从表单的cleaned_data里获取参数
        cleaned_data = self.form.cleaned_data
        course = cleaned_data.get('course')
        department = cleaned_data.get('department')
        semester = cleaned_data.get('semester')
        
        # 拼接成带查询参数的URL
        base_url = reverse('office:members_list')
        query_params = f'?course={course}&department={department}&semester={semester}'
        return base_url + query_params

在ListView里获取参数并过滤查询集

更新MembersList类的get_queryset方法,从请求的GET参数里拿到值,然后过滤数据:

class MembersList(generic.ListView):
    template_name = "office/crs_att.html"
    context_object_name = 'members'

    def get_queryset(self):
        queryset = Members.objects.all()
        
        # 从GET请求里获取过滤参数
        course = self.request.GET.get('course')
        department = self.request.GET.get('department')
        semester = self.request.GET.get('semester')

        # 逐个参数过滤(注意:这里假设Members模型的字段名和表单字段一致,不一致的话要调整)
        if course:
            queryset = queryset.filter(course__iexact=course)  # iexact是不区分大小写匹配,用exact则区分
        if department:
            queryset = queryset.filter(department__iexact=department)
        if semester:
            try:
                # 把字符串转成整数(因为semester是IntegerField)
                semester_int = int(semester)
                queryset = queryset.filter(semester=semester_int)
            except ValueError:
                # 如果参数不是合法整数,跳过这个过滤条件
                pass
        
        return queryset

方法2:通过Session存储参数(不暴露在URL,适合敏感数据)

如果不想让过滤条件出现在URL里,可以把表单数据存在Session中,然后在ListView里读取。

修改FormView,把数据存入Session

class AttendanceForm(generic.FormView):
    form_class = AttendanceForm
    template_name = 'office/crsatt_form.html'
    success_url = reverse_lazy('office:members_list')

    def form_valid(self, form):
        # 把清洗后的表单数据存入session
        self.request.session['attendance_filters'] = form.cleaned_data
        return super().form_valid(form)

在ListView里读取Session并过滤

class MembersList(generic.ListView):
    template_name = "office/crs_att.html"
    context_object_name = 'members'

    def get_queryset(self):
        queryset = Members.objects.all()
        # 从session获取过滤参数
        filters = self.request.session.get('attendance_filters', {})
        
        if filters:
            # 直接用字典解构过滤(同样要确保模型字段名和表单字段一致)
            queryset = queryset.filter(**filters)
            # 可选:用完后删除session里的参数,避免用户刷新页面还保留过滤条件
            del self.request.session['attendance_filters']
        
        return queryset

额外注意事项

  • 确保Members模型里有和表单字段对应的字段(比如course、department、semester),如果字段名不一样,要调整filter里的键(比如模型里是course_name,那就要写course_name=course)
  • 可以在forms.py里给字段加验证规则,比如给semester加min_value=1,避免无效输入:
    semester = forms.IntegerField(min_value=1)
    
  • 如果用户直接访问结果页面(不经过表单提交),两种方法都会返回全部数据,你可以根据需求改成返回空查询集或者提示用户先提交表单。

内容的提问来源于stack exchange,提问作者The Sagittarius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 20:08:10