0

ユーザーの検索結果をエクスポートしようとしています。Django + Haystack + Solr を使用して検索結果を生成しています。現在、SearchQuerySetCSV を書き出すための を作成するために、検索結果ページから CSV を生成するビューにクエリ パラメータを渡し、そこで を再構築してSearchQuerySetいます。ファセット、複数のモデルなどを使用して検索がかなり複雑であり、SearchForm. 結果をエクスポートビューに直接渡す簡単な方法があるはずです。助言がありますか?

編集

私は自分の解決策を考え出し、変更されたすべてのコードを回答に入れました。下記を参照してください。願わくば、これで他の誰かが 1 週間頭を壁にぶつけるのを防ぐことができます!

4

1 に答える 1

0

さて、私はついにこれを自分で理解しました。基本的に、HTML に 2 つ目の送信ボタンを追加してから、SearchFormjavascript を使用してアクションを「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'

ビュー.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/')
于 2015-04-08T19:46:40.320 に答える