OneToOne 模型的 FileField 中的文件如何被访问、读入 views.py 并传递给模板?

How is the file from OneToOne Model's FileField accessed, read in views.py and passed to template?

我正在开发一个简单的数据可视化应用程序,用户可以在其中注册、登录、上传文件并可视化其内容。

我正在使用默认的 User 模型,以及一个与 User 模型具有一对一关系的 Detail 模型。 Detail有3个字段,分别是:

OneToOne(User)
FileField()
TextField()

现在,我想访问保存在FileField, in views.pyand read it's content, then visualize it using Python'sNumPyandMatplotlib`中的文件,最后在前端显示可视化结果。

我需要关于如何开始和完成这项任务的指导?基本上,我需要深入指导如何访问和阅读 views.py?

中的文件

我的models.py是:

class Detail(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    file = models.FileField(verbose_name="CSV File", upload_to='csv_files/')
    file_desc = models.TextField("CSV File Description")

    def __str__(self):
        return ("{} ({} {})".format(self.user.email, self.user.first_name, self.user.last_name))

views.py中,我是这样处理的:

class VisualizeAPI(View):
    template_name = 'accounts/visualize.html'

    def get(self, request):
        msg = {'message': "Please login to view this page."}
        
        if request.user.is_authenticated:
            detail, _ = Detail.objects.get_or_create(user=request.user)
            context = {'detail': detail}

            return render(request, self.template_name, context)

        return render(request, self.template_name, msg)

template中,我是这样处理的:

<body>
    <h1>Visualized Details</h1>
 
    {% if request.user.is_authenticated %}
    {{ detail }}
    {% else %}
    <h2>{{ message }}</h2>
    {% endif %}
</body>

但是它没有在前端打印文件的内容。 我很高兴能提供适当的方法和指导。

您需要在您的视图中解析 CSV 文件,然后将其传递给您的模板。

import csv
from io import StringIO


class VisualizeAPI(View):
    template_name = "accounts/visualize.html"

    def get(self, request):
        msg = {"message": "Please login to view this page."}

        if request.user.is_authenticated:
            detail, _ = Detail.objects.get_or_create(user=request.user)
            if detail.file:
                # Read file from detail object
                file = detail.file.read().decode("utf-8")
                # Parse file as csv
                csv_data = csv.reader(StringIO(file), delimiter=",")
            else:
                csv_data = None
            context = {
                "detail": detail,
                "csv_data": csv_data,
            }

            return render(request, self.template_name, context)

        return render(request, self.template_name, msg)

然后您可以在模板中打印 csv 文件的每一行。

<body>
  <h1>Visualized Details</h1>

  {% if request.user.is_authenticated %}
  {{ detail }}
  {% for row in csv_data %}
    {{ row }}
  {% endfor %}
  {% else %}
  <h2>{{ message }}</h2>
  {% endif %}
</body>