Экспорт результатов поиска в стоге сена

Я пытаюсь экспортировать результаты поиска пользователя. Я использую Django + Haystack + Solr для получения результатов поиска. В настоящее время для создания SearchQuerySet чтобы выписать CSV, я передаю параметры запроса со страницы результатов поиска в представление, производящее CSV, и перестраиваю SearchQuerySet там. Это настоящая боль, потому что поиск довольно сложный, с фасетами, несколькими моделями и т. Д., И постоянно возникают ошибки, когда я делаю изменения в SearchForm, Кажется, должен быть простой способ просто передать результаты непосредственно в представление экспорта. Какие-либо предложения?

РЕДАКТИРОВАТЬ

Я нашел свое собственное решение и поместил весь измененный код в ответ. Пожалуйста, смотрите ниже. Надеюсь, это не позволит кому-то еще неделю биться головой об стену!

1 ответ

Решение

Хорошо, я наконец-то понял это сам. Я в основном должен был добавить вторую кнопку отправки в HTML для моего SearchForm а затем использовал javascript, чтобы перенаправить действие в мое представление "search_export". Поскольку при отправке формы фасеты не передаются, мне пришлось получить фасеты из запроса (в шаблоне страницы поиска) и передать их для просмотра довольно хакерски через URL. Затем аспекты должны быть переоценены в представлении. Я вставлю весь мой код ниже:

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/')
Другие вопросы по тегам