将 csv 上传到内存中并将 json 发送到 api 的 Django 页面

Posted

技术标签:

【中文标题】将 csv 上传到内存中并将 json 发送到 api 的 Django 页面【英文标题】:Django page that uploads csv in memory and sends off json to api 【发布时间】:2021-12-28 16:20:06 【问题描述】:

我正在尝试使用 django 为用户创建一个与 api 交互的站点。该网站的第一页需要是一个csv上传,然后将数据解析为json格式并发送到api。

我已经阅读了民意调查应用程序的 django 教程,并且对 django 了解甚少。但这真的是压倒性的。

我能够从这个网站上传 csv 文件:csv upload

但这会将数据存储到模型中。 (最终可能没问题。)但我想我可以上传 csv 并将其直接转换为 json 而无需存储?

我想我只是在寻找有关如何进行简单上传的方向,其中上传按钮只是触发 csv 摄取、格式化和 api 请求的提交。我认为我唯一需要存储的是请求的响应。 (它返回一个我需要的 ID,以便通过不同的 API 调用检索结果。)

我还注意到当前视图仅使用新行更新表。所以我能够在 csv 读取循环之前添加“profile.objects.all().delete()”,以便在每次上传之前清空表格。

CSV 上传:

name,email,address,phone,profile
Sima,simathapa111@gmail.com,Nadipur,14151234567,"She is a developer, researcher and food-lover."
Gita,geeta12@outlook.com,Pokhara,(415) 123-4567,"Geeta is a teacher, she loves to play and dance."
Ram,ram123@gmail.com,Kathmandu,17735356563,Ram delivers food.

JSON 格式:


    "peopleRecords": [
        
            "name": "Sima",
            "email": "simathapa111@gmail.com",
            "address": "Nadipur",
            "phone": "14151234567",
            "profile": "She is a developer, researcher and food-lover."
        ,
        
            "name": "Gita",
            "email": "geeta12@outlook.com",
            "address": "Pokhara",
            "phone": "(415) 123-4567",
            "profile": "Geeta is a teacher, she loves to play and dance."
        ,
        
            "name": "Ram",
            "email": "ram123@gmail.com",
            "address": "Kathmandu",
            "phone": "17735356563",
            "profile": "Ram delivers food."
        
]

型号:

from django.db import models
# Create your models here.
from phonenumber_field.modelfields import PhoneNumberField
class Profile(models.Model):
    name = models.CharField(max_length=150)
    email = models.EmailField(blank=True)
    address = models.CharField(max_length=50)
    phone = models.CharField(max_length=150,unique=True)
    profile = models.TextField()
    def __str__(self):
        return self.name

管理员:

from django.contrib import admin
# Register your models here.
from .models import Profile
admin.site.register(Profile)

查看:

import csv, io
from django.shortcuts import render
from django.contrib import messages
# Create your views here.
# one parameter named request
def profile_upload(request):
    # declaring template
    template = "profile_upload.html"
    data = Profile.objects.all()
# prompt is a context variable that can have different values      depending on their context
    prompt = 
        'order': 'Order of the CSV should be name, email, address,    phone, profile',
        'profiles': data    
              
    # GET request returns the value of the data with the specified key.
    if request.method == "GET":
        return render(request, template, prompt)
    csv_file = request.FILES['file']
    # let's check if it is a csv file
    if not csv_file.name.endswith('.csv'):
        messages.error(request, 'THIS IS NOT A CSV FILE')
    data_set = csv_file.read().decode('UTF-8')
    # setup a stream which is when we loop through each line we are able to handle a data in a stream
io_string = io.StringIO(data_set)
next(io_string)
for column in csv.reader(io_string, delimiter=',', quotechar="|"):
    _, created = Profile.objects.update_or_create(
        name=column[0],
        email=column[1],
        address=column[2],
        phone=column[3],
        profile=column[4]
    )
context = 
return render(request, template, context)

模板:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    % if messages %
        % for message in messages %
            <div>
<!--                | means OR operator-->
                <strong>message|safe</strong>
            </div>
        % endfor %
    % else %
    order
    <form action="" method="POST" enctype="multipart/form-data">
        % csrf_token %
        <label for="file1"> Upload a file</label>
        <input type="file" id="file1" name="file">
        <small>Only accepts CSV files</small>
        <button type="submit">Upload</button>
    </form>
    % endif %
    % for profile in profiles %
    profile.name
    % endfor %
</body>
</html>

网址:

from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static

from csvfile.views import profile_upload

urlpatterns = [
    path('admin/', admin.site.urls),
    path('upload-csv/', profile_upload, name="profile_upload"),
]

【问题讨论】:

【参考方案1】:

是的,您可以将信息放入 json 中,而无需将其保存在数据库中。但无论如何,您必须保存 csv 文件,然后处理该文件。保存文件后,您甚至可以使用下面的类似代码执行相同操作:

csv_file = open("csv_file.csv")
csv_file.readline()  # To cross the first line.
data = []
for line in csv_file:
    name, email, address, phone, profile = line.split(",")
    data.append(
        "name": name,
        "email": email,
        "address": address,
        "phone": phone,
        "profile": profile
    )

# return data ...

【讨论】:

以上是关于将 csv 上传到内存中并将 json 发送到 api 的 Django 页面的主要内容,如果未能解决你的问题,请参考以下文章

在 React(客户端)中上传 .json 文件并将其发送到 Node(服务器端)

我想将图像 URL 作为 json 数据上传到我的 Angular 表单并将其发送到服务器。图片 URL 来自服务器响应

将 CSV 文件从 JSON 数据上传到 S3 存储桶

通过 CSV 导出/导入 mysql json 对象

如何在 firebase 存储上上传多个文件并将访问 url 和元数据作为 json 或 csv 文件获取? [关闭]

如何将 CSV 从 React 应用程序发送到 Node.js 服务器?