首页 > 解决方案 > 在 Django 模板上显示上传的 csv 文件

问题描述

我有一个项目接受上传的 .csv 文件并通过 models.py 在管理员上显示。我想要发生的是在模板上显示这些上传的 .csv 文件。

我的观点是:

def data_upload(request):
    template = "home.html"

    if request.method == 'GET':
        return render(request, template)

    csv_file = request.FILES['file']
    if not csv_file.name.endswith('.csv'):
        messages.error(request, 'Please upload a .csv file.')

    data_set = csv_file.read().decode('ISO-8859-1')
    io_string = io.StringIO(data_set)
    next(io_string)
    for column in csv.reader(io_string, delimiter=','):
        _, created = Table.objects.update_or_create(
            page=column[0], 
            keyword=column[1], 
            interval=column[2], 
            email=column[3], 
            notes=column[4], 
            billing=column[5],
        )
    context = {
    'tables': Table.objects.all()
    }
    return render(request, template, context)

当我上传 .csv 文件时,这些视图已经开始工作了。

在 home.html 文件上,这就是我所做的:

                       <table class="table table-condensed">
                        <thead>
                        <tr>
                            <th>...</th>
                        </tr>
                        </thead>
                        <tbody>
                        <tr>
                            <th class="center-align" scope="row"><i class="small material-icons green">check</i></th>
                            {% for t in tables %}
                            <td class="center-align">{{t.page}}</td>
                            <td class="center-align">{{t.keyword}}</td>
                            <td class="center-align">{{t.interval}}</td>
                            <td class="center-align">{{t.email}}</td>
                            <td class="center-align">{{t.notes}} </td>
                            <td class="center-align">{{t.billing}}</td>
                            {% endfor %}
                        </tr>
                       </table>

如何正确迭代模板以显示我在 html 文件中上传的内容?

标签: djangocsvdjango-templates

解决方案


如果您不上传文件,则代码不会超过第一次返回

除非上传 CSV,否则代码会在此处停止,因此不会向模板发送数据。这就是 {{ tables }} 返回空白的原因。当数据在数据库中时,模板中的 {{tables}} 永远不会在此渲染中填充。

    if request.method == 'GET':
        return render(request, template)

仅当实际上传 CSV 时,才会输出任何内容并填写表格。任何不是来自绿色大上传按钮的请求都不会运行会为模板中的 {{tables}} 提供任何数据的代码。

以下代码仅在当时上传 CSV 时运行。

csv_file = request.FILES['file']
    if not csv_file.name.endswith('.csv'):
        messages.error(request, 'Please upload a .csv file.')

    data_set = csv_file.read().decode('ISO-8859-1')
    io_string = io.StringIO(data_set)
    next(io_string)
    for column in csv.reader(io_string, delimiter=','):
        _, created = Table.objects.update_or_create(
            page=column[1], 
            keyword=column[2], 
            interval=column[3], 
            email=column[4], 
            notes=column[5], 
            billing=column[6],
        )
    context = {
        'tables': Table.objects.all()
    }
    print(Table.objects.all())
    return render(request, template, context)

这行得通吗?

context = {'tables': Table.objects.all()}

这假定 Table 中的唯一元素是 CSV 中的元素。

编辑,如何修复模板

改变这个

                            <tr>
                                <th class="center-align" scope="row"><i class="small material-icons green">check</i></th>
                                {% for t in tables %}
                                <td class="center-align">{{t.page}}</td>
                                <td class="center-align">{{t.keyword}}</td>
                                <td class="center-align">{{t.interval}}</td>
                                <td class="center-align">{{t.email}}</td>
                                <td class="center-align">{{t.notes}} </td>
                                <td class="center-align">{{t.billing}}</td>
                                {% endfor %}
                            </tr>
{% for t in tables %}
                            <tr>
                                <th class="center-align" scope="row"><i class="small material-icons green">check</i></th>

                                <td class="center-align">{{t.page}}</td>
                                <td class="center-align">{{t.keyword}}</td>
                                <td class="center-align">{{t.interval}}</td>
                                <td class="center-align">{{t.email}}</td>
                                <td class="center-align">{{t.notes}} </td>
                                <td class="center-align">{{t.billing}}</td>

                            </tr>
                            {% endfor %}

对此在home.html

基本上,让<tr></tr>标签进入 for 循环内部而不是外部。


推荐阅读