问题:
我正在使用一个具有“ StudentListView”的Web应用程序,该应用程序应具有以下功能:
.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)
此视图寻求提供的功能在许多网站上都很普遍,因此显然可以解决。但是,当这些过滤器已应用于先前的查询集时,我目前对如何允许用户导出过滤的列表一无所知。
答案 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。但是可能某些浏览器可能配置为不发送引荐来源网址。