Django-上一个请求的访问参数

时间:2019-07-31 08:00:49

标签: django

问题:

我正在使用一个具有“ StudentListView”的Web应用程序,该应用程序应具有以下功能:

  1. 显示学生列表
  2. 上方有一个搜索框,允许用户过滤/搜索此列表(提交“ Peter”应返回所有姓名均为“ Peter”的学生)
  3. “导出”按钮应允许用户将该列表(可能已过滤!)导出到.csv文件

我已经实现了以下代码,以允许用户过滤列表,该列表按预期工作。我还创建了一个export_students函数,该函数为提供的查询集中的所有学生创建一个.csv文件。此功能也可以按预期工作。

但是,在导出过滤列表时,该程序的行为不符合用户期望。用户首先将通过提供搜索参数来过滤列表,这将触发请求并刷新页面。然后,用户按下“导出”按钮,但由于他没有重新提交搜索参数(为什么,他看到的列表已被过滤,因此未在请求中提供),因此csv文件包含数据库,而不是他期望的过滤选择。

可能的解决方案

如果我可以某种方式存储请求的搜索参数,并在以下request.GET包含exportstudents关键字的情况下进行检索,则可以解决此问题。但是我不确定如何才能做到这一点。我得到的最接近的结果是使用javascript将搜索参数附加到Export按钮的值上。但这意味着request.GET['exportstudents']将整个搜索查询作为其值(为简单起见,我在代码示例中删除了大多数搜索/过滤器选项,但这些参数字符串可能会变得很长)

我当然可以使用复杂的正则表达式解析结果,但是对于一个可能更容易解决的问题而言,这似乎是一个非常复杂的解决方案。

代码

同样,为了简单起见,我删除了大多数过滤器参数,但是下面的代码应该很好地说明我的视图的功能。

HTML将关键字附加到请求.GET参数,如果存在的话,该关键字可用于过滤查询集或触发export_students函数。


<form method="get">
  <input name="search_query" type="text" class="form-control"
     value="{% if request.GET.q %}{{ request.GET.q }}{% endif %}"
     placeholder="Find student"
  />
  <button type="submit">Filter Students</button></span>
</form>

<form id='exportform' class="col-md-5 " method="get" action="">
   <div class="input-group">
     <button id='export' name="exportstudents" value="true">Export Students</button>
   </div>
</form>

class StudentListView(generic.ListView)

    def get_queryset(self):
        field = self.request.GET.get('field', 'last_name')
        qs = Student.objects.all()
        search_query = self.request.GET.get('search_query', None)
        if search_query:
            qs = qs.filter(
                Q(first_name__icontains=search_query) |
                Q(last_name__icontains=search_query) |
                Q(email_parents__icontains=search_query)
            )
        return qs

    def get(self, request, *args, **kwargs):
        if 'exportstudents' in self.request.GET:
            qs = self.get_queryset()
            file = export_students(qs)
            content = 'attachment; filename="{}_{}.csv"'.format(
                u'Student_export',
                timezone.now().strftime('%d-%m_%H:%M')
            )
            response = StreamingHttpResponse(
                file, content_type='text/csv')
            response['Content-Disposition'] = content
            return response
        return super(UserListView, self).get(request, *args, 
            **kwargs)

此视图寻求提供的功能在许多网站上都很普遍,因此显然可以解决。但是,当这些过滤器已应用于先前的查询集时,我目前对如何允许用户导出过滤的列表一无所知。

2 个答案:

答案 0 :(得分:1)

出口学生也是一种形式。因此,您可以在此处将参数添加为隐藏字段-现在您现有的视图代码将可以使用。

<form id='exportform' class="col-md-5 " method="get" action="">
   <input type="hidden" name="search_query" value="{{ request.GET.search_query }}"
   <div class="input-group">
     <button id='export' name="exportstudents" value="true">Export Students</button>
   </div>
</form>

或者,仅使用带有两个按钮的单个表单:

<form method="get">
  <input name="search_query" type="text" class="form-control"
     value="{% if request.GET.q %}{{ request.GET.q }}{% endif %}"
     placeholder="Find student"
  />
  <button type="submit">Filter Students</button></span>

   <div class="input-group">
     <button id='export' name="exportstudents" value="true">Export Students</button>
   </div>
</form>

同样,这将正常工作(尽管我怀疑您也是request.GET.search_query的意思。)

答案 1 :(得分:1)

您还可以使用请求上的request.META.get('HTTP_REFERER')标头来访问上一个请求的GET。但是可能某些浏览器可能配置为不发送引荐来源网址。