Working browser-upload view

This commit is contained in:
Scot Hacker 2019-03-10 14:23:17 -07:00
parent c93be50864
commit 37a698c77b
5 changed files with 109 additions and 0 deletions

View file

@ -68,6 +68,7 @@ class CSVImporter:
self.summary_msgs.append(f"\nProcessed {self.line_count} CSV rows") self.summary_msgs.append(f"\nProcessed {self.line_count} CSV rows")
self.summary_msgs.append(f"Upserted {self.upsert_count} rows") self.summary_msgs.append(f"Upserted {self.upsert_count} rows")
self.summary_msgs.append(f"Skipped {self.line_count - self.upsert_count} rows")
_res = { _res = {
"errors": self.error_msgs, "errors": self.error_msgs,

View file

@ -0,0 +1,80 @@
{% extends "todo/base.html" %}
{% load static %}
{% block title %}Import CSV{% endblock %}
{% block content %}
<h2>
Import CSV
</h2>
<p>
Batch-import tasks by uploading a specifically-formatted CSV.
See documentation for formatting rules.
Successs and failures will be reported here.
</p>
{% if results %}
<div class="card mb-4">
<div class="card-header">
Results of CSV upload
</div>
<div class="card-body">
<p>
<b>Summary:</b>
</p>
<ul>
{% for line in results.summaries %}
<li>{{ line }}</li>
{% endfor %}
</ul>
<p>
<b>Upserts (tasks created or updated):</b>
</p>
<ul>
{% for line in results.upserts %}
<li>{{ line }}</li>
{% endfor %}
</ul>
<p>
<b>Errors (tasks NOT created or updated):</b>
</p>
<ul>
{% for error_row in results.errors %}
{% for k, error_list in error_row.items %}
<li>CSV row {{ k }}</li>
<ul>
{% for err in error_list %}
<li>{{ err }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endfor %}
</ul>
</div>
</div>
{% endif %}
<div class="card">
<div class="card-header">
Upload Tasks
</div>
<div class="card-body">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div>
<input type="file" name="csvfile" accept="text/csv">
</div>
<button type="submit" class="btn btn-primary mt-4">Upload</button>
</form>
</div>
</div>
{% endblock %}

View file

@ -70,4 +70,9 @@ urlpatterns = [
'search/', 'search/',
views.search, views.search,
name="search"), name="search"),
path(
'import_csv/',
views.import_csv,
name="import_csv"),
] ]

View file

@ -8,3 +8,4 @@ from todo.views.reorder_tasks import reorder_tasks # noqa: F401
from todo.views.search import search # noqa: F401 from todo.views.search import search # noqa: F401
from todo.views.task_detail import task_detail # noqa: F401 from todo.views.task_detail import task_detail # noqa: F401
from todo.views.toggle_done import toggle_done # noqa: F401 from todo.views.toggle_done import toggle_done # noqa: F401
from todo.views.import_csv import import_csv # noqa: F401

22
todo/views/import_csv.py Normal file
View file

@ -0,0 +1,22 @@
from django.contrib.auth.decorators import login_required, user_passes_test
from django.http import HttpResponse
from django.shortcuts import render
from todo.operations.csv_importer import CSVImporter
from todo.utils import staff_check
@login_required
@user_passes_test(staff_check)
def import_csv(request) -> HttpResponse:
"""Import a specifically formatted CSV into stored tasks.
"""
ctx = {}
if request.method == "POST":
filepath = request.FILES.get('csvfile')
importer = CSVImporter()
results = importer.upsert(filepath)
ctx["results"] = results
return render(request, "todo/import_csv.html", context=ctx)