我正在尝试导出用户搜索的结果。我正在使用Django + Haystack + Solr来生成搜索结果。目前,要创建SearchQuerySet
以写出CSV,我将查询参数从搜索结果页面传递到生成CSV并在那里重建SearchQuerySet
的视图。这是一个真正的痛苦,因为搜索非常复杂,有方面,多个模型等,当我对SearchForm
进行修改时会不断出现错误。似乎应该有一种简单的方法将结果直接传递给导出视图。有什么建议吗?
修改
我找到了自己的解决方案并将所有修改过的代码放在答案中。请看下面。希望这可以防止其他人在墙上撞墙一周!
答案 0 :(得分:0)
好的,我终于弄明白了。我基本上不得不为我的SearchForm
的html添加第二个提交按钮,然后使用javascript将操作重定向到我的" search_export"视图。由于在提交表单时没有传递facet,我必须从请求中获取facet(在搜索页面模板中)并通过url将其传递给相当hackish。然后必须在视图中重新评估构面。我将在下面粘贴所有代码:
search.html
{% block content %}
<form method="get" action=".">
<!-- Advanced Search Box -->
<div class="row">
<div class="col-lg-12">
<h2 class="text-center">Advanced Search</h2>
<!-- Search Form Fields Here -->
<ul class="list-inline center-block text-center adv-form">
<li>
<p><input type="submit" value="Search"></p>
</li>
<li>
<p><input type="submit" id="export" value="Export Results"></p>
</li>
</ul>
</div>
</div>
<!-- End Advanced Search Box -->
<!-- Search Results are displayed here -->
{% endblock %}
<!-- Search Unique JS -->
{% block js %}
{{ block.super }}
<script>
$(document).ready(function () {
$("#export").click(function() {
$(this).closest("form").attr('action', "{% query_params_getlist request 'selected_facets' as facets %}{% url 'search_export' facets %}");
});
});
</script>
{% endblock %}
<!-- End Search Unique JS -->
urls.py
urlpatterns = patterns('base.views',
# all the other url patterns go here
url(r'^search_export/(?P<selected_facets>\S+)/$', 'search_export', name='search_export'),
)
base_tags.py
@register.assignment_tag
def query_params_getlist(request, param):
params = request.GET.getlist(param)
if len(params) > 0:
query_string = ""
for p in params:
query_string += p + '&'
return query_string
return 'None'
views.py
def search_export(request, selected_facets):
if request.method == 'GET':
form = AdvModelSearchForm(request.GET)
if form.is_valid():
qs = form.search()
#deal with facets
facets = selected_facets.split("&")
for facet in facets:
if ":" not in facet:
continue
field, value = facet.split(":", 1)
if value:
# faceted fields are stored in a hierarchy, so I check for any document with the given facet or its children
control_value = ControlField.objects.filter(pk=qs.query.clean(value))
if control_value:
value_tree = control_value[0].get_descendants(include_self=True)
sq = SQ()
for index, node in enumerate(value_tree):
kwargs = {str("%s" % (field)) : str("%s" % (node.id))}
if index == 0:
sq = SQ(**kwargs)
else:
sq = sq | SQ(**kwargs)
qs = qs.filter(sq)
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="search_results.csv"'
writer = csv.writer(response)
titles = []
rows = []
for result in qs:
row = []
row_dict = {}
properties = result.text #IMPT - this field must be a MultiValueField in the Haystack search_indexes.py file or this won't return a list
for each_prop in properties:
prop_pair = each_prop.split(':', 1)
if len(prop_pair) < 2:
continue
prop_name = smart_str(prop_pair[0].strip())
prop_value = smart_str(prop_pair[1].strip())
if not (prop_name in titles):
column_index = len(titles)
titles.append(prop_name)
else:
column_index = titles.index(prop_name)
if column_index in row_dict:
prop_value = row_dict[column_index] + '; ' + prop_value
row_dict[column_index] = prop_value
for i in range(len(titles)):
if i in row_dict:
row.append(row_dict[i])
else:
row.append('')
rows.append(row)
writer.writerow(titles)
for each_row in rows:
writer.writerow(each_row)
return response
return HttpResponseRedirect('/failed_export/')