Importieren Sie mehrere CSVs, verarbeiten Sie sie und geben Sie die Ergebnisse im CSV-Format zurück. Dieses Mal werden wir dies anhand des folgenden Falls implementieren.
Das folgende CSV ist an einer Universität erhältlich.
available.csv
enthält Informationen darüber, wie viel Kapazität jede Klasse hat.
reserved.csv
enthält Informationen darüber, wie viele Schüler in jeder Klasse Unterricht nehmen möchten.
Wenn Sie diese Dateien dieses Mal im Browser hochladen, erstellen Sie eine App, die eine CSV herunterlädt, die anzeigt, wie viel Speicherplatz jede Klasse derzeit hat.
Auf der Vorderseite gibt es hauptsächlich die folgenden zwei Bewegungen. ①: Datei hochladen (2): Spucken Sie basierend auf der hochgeladenen Datei die CSV aus, die die Freiheit jeder Klasse angibt.
Es wird davon ausgegangen, dass der Django-Projektordner (myproject
) und der App-Ordner ( app
) bereits vorhanden sind. Wenn nicht, siehe hier.
Diesmal ist die Ordnerstruktur wie folgt.
├─app
│ │ admin.py
│ │ apps.py
│ │ forms.py
│ │ functions.py
│ │ models.py
│ │ tests.py
│ │ views.py
│ │ __init__.py
│ │
│ ├─migrations
│ │ __init__.py
│ │
│ ├─static
│ │ └─upload
│ │ test.txt
│ │
│ └─templates
│ index.html
│
├─myproject
│ │ settings.py
│ │ urls.py
│ │ wsgi.py
│ │ __init__.py
│ │
│ └─static
│ humans.txt
│
└─staticfiles
Definieren Sie zunächst die Formulare in forms.py
wie folgt, damit Sie die Datei hochladen können.
from django import forms
#Klassenzimmerformular definieren
class ClassroomForm(forms.Form):
availablity = forms.FileField()
reservation = forms.FileField()
Um das erstellte Formular auf der Vorderseite anzuzeigen, übergeben Sie das Formular wie unten gezeigt mit "views.py" an HTML.
from django.shortcuts import render
from app.forms import ClassroomForm
def index(request):
###Index ClassroomForm.Übergabe an HTML
classroom = ClassroomForm()
return render(request,"index.html",{'form':classroom})
Verwenden Sie nun "{{form.as_p}}" in "index.html" und ziehen Sie das Formular wie folgt.
<body>
<form method="POST" class="post-form" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
</body>
Wenn Sie das Formular so senden, wie es ist, werden die POST-Informationen an die Indexmethode von views.py übergeben. Schreiben Sie den Index also wie folgt um, damit die POST-Verarbeitung ausgeführt wird.
from django.shortcuts import render
from django.http import HttpResponse
from app.functions import process_files
from app.functions import write_into_csv
from app.forms import ClassroomForm
from django.template import loader
import csv
def index(request):
if request.method == 'POST':
classroom = ClassroomForm(request.POST, request.FILES)
#Wenn sich Daten im Klassenzimmer befinden
if classroom.is_valid():
availability = request.FILES['availablity']
reservation = request.FILES['reservation']
#implement process_files
csv_data = process_files(availability, reservation)
#download result as a csv format
response = write_into_csv(csv_data)
return response
else:
###Index ClassroomForm.Übergabe an HTML
classroom = ClassroomForm()
return render(request,"index.html",{'form':classroom})
Hier rufen wir zwei Methoden auf, "process_files" und "write_into_csv", die in "functions.py" definiert sind. Im Folgenden wird diese Methode definiert.
Definieren Sie die in views.py
verwendete Logik in functions.py
.
import csv
from django.http import HttpResponse
### Process csv files
def process_files(availability, reservation):
""" Description
:type availability:
:param availability:
:type reservation:
:param reservation:
:raises:
:rtype:
"""
availability_dict = convert_to_dict(availability)
reservation_dict = convert_to_dict(reservation)
csv_data = []
courses = list(availability_dict)
for course in courses:
remaining = availability_dict[course] - reservation_dict[course]
row = [course, remaining]
csv_data.append(row)
return csv_data
def convert_to_dict(file):
""" Description
:type file:
:param file:
:raises:
:rtype:
"""
data = file.read().decode("utf-8-sig")
lines = data.split("\r\n")
dict = {}
for line in lines:
fields = line.split(",")
course = fields[0]
capacity = int(fields[1])
dict[course] = capacity
return dict
def write_into_csv(csv_data):
""" Description
:type csv_data:
:param csv_data:
:raises:
:rtype:
"""
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="download.csv"'
writer = csv.writer(response)
for row in csv_data:
writer.writerow(row)
return response
Mit dem oben Gesagten wurde die entworfene Funktion implementiert.
Demo
Bitte tun Sie gerne, wenn Sie es hilfreich finden.
Github https://github.com/norifumi92/csv_uploader/tree/develop
https://www.javatpoint.com/django-file-upload https://codepen.io/adamlaki/pen/VYpewx https://www.pythoncircle.com/post/30/how-to-upload-and-process-the-csv-file-in-django/ https://into-the-program.com/customize-input-type-file/ https://docs.djangoproject.com/en/3.0/topics/forms/