从 django 应用程序下载一个 text/csv 文件,该文件从数据库查询中填充 HTML table

Download a text/csv file from django app that populates HTML table from a database query

我目前有一个 Django 应用程序,我可以搜索它来查询我的数据库,该数据库从查询中填充 html table。

我的 app_home.html 看起来像这样:

{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
    <title>RESULTS APP</title>
</head>
   <form method="get" action="results/">
       <div class="SearchBar"><input type="text" name="lab_number"></div>
       <input class='input_button' type='submit'>
   </form>

<body></body>
</html>

这是我的 views.py:

def from_samrun(request):    
    if request.GET:
        lab_query = request.GET['lab_number']
        var_list = VarSamRun.objects.filter(sample=lab_query)
        if var_list:
            return render(request, 'results/varlist.html', {'var_list': var_list})
        else:
            return render(request, 'results/varlist.html', {'query': [sam_query]})
    else:
        return render(request, 'results/varlist.html' {'error': 'Error'})

这会将我带到我的 varlist.html 模板:

{% load staticfiles %}
<!DOCTYPE html>
<html>
<head><title>Results page</title></head>

<body>
    <div>

        {% if var_list %}

              {% for v in var_list %}

                <tr>
                <td class='varsrow' width='100'>{{v.sample}}</td>
                <td class='varsrow' width='100'>{{v.gene}}</td>
                <td class='varsrow' width='200'>{{v.variant}}</td>
                <td class='varsrow' width='150'>{{v.cds}}</td>
                <td class='varsrow' width='150'>{{v.protein}}</td>
                <td class='varsrow' width='200'>{{v.consequence}}</td>
                <td class='varsrow' width='200'>{{v.run}}</td>

                <td class='varsrow' width='300'>{{v.annotation}}</td>
                </tr>

            {% endfor %}    

      {% elif query %}

                <h5>Search using: "

                {% for q in query %}
                    {{q}}
                {% endfor %}

            " did not return any results</h5>

      {% else %}

            <h5>{{annotation}}</h5>

     {% endif %}

    </table>
   </div>
  </body>
</html>

我的网址是:

    urlpatterns = [
    url(r'^results/$', views.results_app, name='results_app'),
    url(r'results/varlist/$', views.from_samrun, name='from_samrun'),

我想在我的 varlist.html 页面上有一个下载按钮,以便在显示 table 时用户可以选择下载 - 导出到 csv 文件。我知道如何将数据写入 csv 并使用另一个视图下载它:

def download_view(request):
    response = HttpResponse('')
    response['Content-Disposition'] = 'attachment; filename=file.csv'   
    writer = csv.writer(response, dialect=csv.excel)
    writer.writerow(some_random_data_list)
    return response

并添加一个表单按钮以下载到我的 varlist.html 页面:

<form action ='download' method='POST'>
    {% csrf_token %}
    <input type='hidden'>
    <input type='submit' value='Download'>
</form>

但我不知道如何将信息从我的第一个视图传递到我的下载视图,或者将 html table 信息作为对象传递到我的下载视图。 (我尝试将 {{var_list}} 作为此 html 表单中的值传递,从中提取数据并创建一个新的查询对象,但这不适用于每个 table 因为它们太大了。

有没有办法将我的 var_list 对象从第一个视图传递到下载视图?我该怎么做呢?

谢谢

也许最快的解决方案是插件: jQuery Datatables

还有一些简单的页面设置。

您可以为您的 download 操作写 URL route。将其指向 urls.py

中的 download_view 视图

事实上,您正在从您的站点请求同一组数据。唯一改变的是格式。所以通常你只是想用像 ?format=csv 这样的 GET 参数请求同一个页面。所以你的视图函数看起来像这样:

def from_samrun(request):    
    if request.GET:
        lab_query = request.GET['lab_number']
        var_list = VarSamRun.objects.filter(sample=lab_query)
        if request.GET['format'] == 'csv':
            response = HttpResponse('')
            response['Content-Disposition'] = 'attachment; filename=file.csv'   
            writer = csv.writer(response, dialect=csv.excel)
            writer.writerow(some_random_data_list)
            return response

        if var_list:
            return render(request, 'results/varlist.html', {'var_list': var_list,'lab_query':lab_query})
        else:
            return render(request, 'results/varlist.html', {'query': [sam_query]})
    else:
        return render(request, 'results/varlist.html' {'error': 'Error'})

你的模板:

<form method='GET'>
    <input type='hidden' name='format' value='csv'>
    <input type='hidden' name='lab_query' value={{lab_query}}>
    <input type='submit'>
</form>