Загрузить в csv результат поиска в Django

Я пытаюсь загрузить CSV из результата поиска. У меня есть следующие представления:

Первым является представление поиска

def binder_search(request):
    if request.method == "POST":
        searched = request.POST['searched']
        binders_searched = Binders.objects.filter(Q(description__contains=searched) | Q(step__name__contains=searched) | Q(status__name__contains=searched))

        return render(request, "binder_search.html", {'searched': searched, 'binders_searched': binders_searched})

    else:
        return render(request, "binder_search.html", {})

Затем создается csv. Это представление создает список всех элементов в базе данных. Я пытаюсь получить результат поиска из вышеуказанного представления, а затем создать файл csv. В итоге я получу CSV-файл, в котором будет только результат поиска.

def binders_csv(request):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename=binders_result.csv'

    # create a csv writer
    writer = csv.writer(response)

    # designate the model
    binders = Binders.objects.all()

    # add column at the heading of csv file
    writer.writerow(['Item Code', 'Description', 'Item Type', 'Current Step', 'Current Status', 'Last change by'])

    # loop thru and output
    for binder in binders:
        writer.writerow([binder.itemcode, binder.description, binder.itemtype, binder.step, binder.status, binder.user])

    return response

Я просматриваю различные решения, но ни одно из них не помогло мне. Есть идеи, как это сделать?

Что я упускаю? Разве вы не можете просто объединить эти два понятия?

def binder_search(request):
    if request.method != "POST":
        return render(request, "binder_search.html", {})

    # POST

    searched = request.POST['searched']
    binders_searched =   Binders.objects.filter(Q(description__contains=searched) | Q(step__name__contains=searched) | Q(status__name__contains=searched))

    # create a csv writer with header writing to response
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename=binders_result.csv'
    writer = csv.writer(response)
    writer.writerow(['Item Code', 'Description', 'Item Type', 'Current Step', 'Current Status', 'Last change by'])

    # loop thru filtered results and output
    for binder in binders_searched:
        writer.writerow(
            [binder.itemcode, binder.description, binder.itemtype, binder.step, binder.status, binder.user]
        )
    return response

Вот решение, которое работает - сделано с помощью nigel222 и фреймворка сессий (request.session). Это решение предоставляет представления, необходимые для отображения результата поиска в шаблоне, а затем нажмите кнопку или ссылку для загрузки именно этого результата в формате CSV. Таким образом, пользователь может получить результат поиска, а затем загрузить его, если захочет. Я искал вокруг, но не смог найти похожее решение, поэтому я размещаю его здесь для других.

Первое представление (binder_search) выполняет поиск и использует request.session для кэширования переменной "searched".

def binder_search(request):
    if request.method == "GET":
        searched = request.GET['searched']

        # Cache variable "searched" for views.binder_search_csv
        request.session['searched'] = searched

        # multiple columns
        binders_searched = Binders.objects.filter(Q(description__contains=searched) | Q(step__name__contains=searched) | Q(status__name__contains=searched))
        return render(request, "binder_search.html", {'searched': searched, 'binders_searched': binders_searched})
    
    else:
        return render(request, "binder_search.html", {})

Во втором представлении используется кэшированная переменная "searched" из представления выше и загружается результат поиска в csv-файл.

def binder_search_csv(request):
    if request.method != "GET":
        return render(request, "binder_search.html", {})

    # Use cached variable from views.binder_search
    searched = request.session['searched']

    binders_searched = Binders.objects.filter(Q(description__contains=searched) | Q(step__name__contains=searched) | Q(status__name__contains=searched))

    # create a csv writer with header writing to response
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename=binders_result.csv'
    writer = csv.writer(response)
    writer.writerow(['Item Code', 'Description', 'Item Type', 'Current Step', 'Current Status', 'Last change by'])

    # loop thru filtered results and output
    for binder in binders_searched:
        writer.writerow(
            [binder.itemcode, binder.description, binder.itemtype, binder.step, binder.status, binder.user]
        )
    return response

Возможно, есть способы упорядочить эти два представления, но в том виде, в котором они есть сейчас, они работают совершенно нормально.

Вернуться на верх