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

Posted

技术标签:

【中文标题】从 django 应用程序下载一个文本/csv 文件,该文件从数据库查询中填充 HTML 表【英文标题】:Download a text/csv file from django app that populates HTML table from a database query 【发布时间】:2017-07-09 16:23:20 【问题描述】:

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

我的 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 页面上有一个下载按钮,以便在显示表格时用户可以选择下载 - 导出到 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 表信息作为对象传递给我的下载视图。 (我尝试将 var_list 作为此 html 表单中的值传递,从中提取数据并创建一个新的查询对象,但这不适用于每个表,因为它们太大了。

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

谢谢

【问题讨论】:

您可以将 lab_query 放在 varlist.html 表单的隐藏字段中,然后在下载视图中再次运行 VarSamRun.objects.filter(sample=lab_query) 【参考方案1】:

事实上,您正在从您的网站请求相同的数据集。唯一改变的是格式。所以通常你只想用像?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>

【讨论】:

我曾想过这样做 - 但这意味着我的查询页面上会有下载按钮,不是吗?那么在用户看到它生成的表格之前,他们会下载它吗?我希望用户查看表格,然后单击该页面底部的下载按钮(已呈现 VarSamRun 对象数据) 如果设置了var_list % if var_list % &lt;form&gt;...&lt;/form&gt; % endif %,你可以签入模板 但是 "request.GET['lab_number']" 不会在此页面上返回任何内容,因为该 GET 表单将丢失其数据:第 1 页 = 'lab number' 的搜索框 > 通过 'lab要查看的数字'... 第 2 页 = 基于使用“实验室编号”的数据库查询呈现的 html 表 - 表底部有一个“下载”按钮... 第 3 页 = 单击下载并导出我的 html 表到 csv 使用不同的视图。 3 获取“实验室编号”数据,因为 GET 数据会丢失? 在这种情况下,我可以参考@thierry-lathuille 评论。请参阅上面的编辑。 您好,抱歉,我错过了将额外的 lab_query 添加到渲染请求中,现在我可以获得初始查询值,是的,我可以从我的下载视图再次运行查询。谢谢,这么简单,但我没有想到!!【参考方案2】:

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

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

【讨论】:

【参考方案3】:

您可以为您的download 操作写URL route。将其指向download_viewurls.py 中查看

【讨论】:

以上是关于从 django 应用程序下载一个文本/csv 文件,该文件从数据库查询中填充 HTML 表的主要内容,如果未能解决你的问题,请参考以下文章

从字符串变量创建包含文本/csv 的 zip 文件的下载

将数据变量从 matlab 保存到 csv 或文本文件

从 HTML 页面上的多个帖子中提取三个文本项到 csv 或类似文件中?

从 API 下载 AngularJS CSV 文件

如何从 django 中可用的大量 csv 文件中选择一个 csv 文件

django 动态生成CSV文件