Django-import-export for csv

django-csv

While learning Django, I’m working hard on a student management app for the online English school I’m currently running (will it ever be finished?).

Read and display student name, class, registration date, renewal date, and birthday in csv.

Add course and student models to models.py

●Include text and pages (units) in Courses

●The database may be changed in the future (lesson evaluations, etc. will be added).

●Reference:https://blog.fragment.co.jp/code/python/django/django-import-export/

from django.contrib.auth.models import AbstractUser
from django.db import models
# Create your models here.

class User(AbstractUser):
    pass


class Courses(models.Model):
    id = models.AutoField(primary_key=True)
    course_name = models.CharField(max_length=50)
    textbook_read = models.CharField(max_length=50)
    textbook_write = models.CharField(max_length=50)
    textbook_listening = models.CharField(max_length=50)
    textbook_speaking = models.CharField(max_length=50)
    unit = models.IntegerField(null=True, blank=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
	    return f"{self.course_name}: {self.textbook_read}, {self.textbook_write}, {self.textbook_listening}, {self.textbook_speaking}"


class Students(models.Model):
    id = models.AutoField(primary_key=True)
    student_name = models.CharField(max_length=50)
    course_name = models.ForeignKey(Courses, on_delete=models.PROTECT, default=1)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    dob = models.DateField(max_length=8, null=True, blank=True)


    class Meta:
           ordering = ['student_name']


    def __str__(self):
        return f"{self.student_name} | {self.course_name}"

●class Meta so that the loaded student list is displayed alphabetically.

views.py

●List display, import and export settings.

from django.http import HttpResponse
from django.urls import reverse_lazy
from django.views import generic
from django.shortcuts import redirect

import csv
import io
from .forms import StudentCsvForm
from .models import Students



class StudentIndex(generic.ListView):
    model = Students


class StudentImport(generic.FormView):
    template_name = 'student/import.html'
    success_url = reverse_lazy('index')
    form_class = StudentCsvForm

    def form_valid(self, form):
        form.save()
        return redirect('index')


def student_export(request):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="students.csv"'
    writer = csv.writer(response)
    for student in Students.objects.all():
        writer.writerow([student.pk, student.student_name, student.score])
    return response

views.py

urls.py list, import, and export

(We will add text csv, etc. later, so name the url student_import, student_export.

from django.urls import path
from . import views

urlpatterns = [
    path('', views.StudentIndex.as_view(), name='index'),
    path('student_import', views.StudentImport.as_view(), name='student_import'),
    path('student_export', views.student_export, name='student_export'),
]

Here is the url.py of the project

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('student.urls')),
]

forms.py: Create forms for import

from django.http import HttpResponse
from django.urls import reverse_lazy
from django.views import generic
from django.shortcuts import redirect

import csv
import io
from .forms import StudentCsvForm
from .models import Students



class StudentIndex(generic.ListView):
    model = Students


class StudentImport(generic.FormView):
    template_name = 'student/import.html'
    success_url = reverse_lazy('index')
    form_class = StudentCsvForm

    def form_valid(self, form):
        form.save()
        return redirect('index')


def student_export(request):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="students.csv"'
    writer = csv.writer(response)
    for student in Students.objects.all():
        writer.writerow([student.pk, student.student_name, student.score])
    return response

base.html: Common settings and menu bar

{% load static %}

<!DOCTYPE html>
<html lang="ja">

<head>
    <!-- Required Meta Tags -->
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <!-- Custom CSS -->
    <link href="{% static 'student/styles.css' %}" rel="stylesheet">
    <!-- Font Awesome -->
    <script src="https://kit.fontawesome.com/bea7d521cb.js" crossorigin="anonymous"></script>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

    <!-- favicon -->
    <link rel="icon" href="{% static 'student/favicon.ico' %}">

    <title>{% block title %}{% endblock %}</title>
</head>

<body>

    <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <a class="navbar-brand" href="{% url 'index' %}">Students</a>

        <div>
            <ul class="navbar-nav mr-auto">
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'student_export' %}"><strong>Export Student</strong></a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'student_import' %}"><i class="fab fa-pagelines"></i> Import Student</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Log Out</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Please Login</a>
                </li>
        </div>
    </nav>

    <div class="body">
        {% block body %}
        {% endblock %}
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
        crossorigin="anonymous"></script>
    <script src="https://code.jquery.com/jquery-3.5.0.js"
        integrity="sha256-r/AaFHrszJtwpe+tHyNi/XCfMxYpbsRg2Uqn0x3s2zc=" crossorigin="anonymous"></script>
</body>

</html>

student_import.html: Create template for import

{% extends "student/base.html" %}

{% block title %} Student List {% endblock %}
{% block body %}
<div class="container" style="text-align: center;">
    <form action="" method="POST" enctype="multipart/form-data">
        {% csrf_token %}
        {{ form.as_ul }}
        <button type="submit">Submit</button>
    </form>
</div>
{% endblock %}

student_list.html: Create student list

Bootstrap Tables 使用

{% extends "student/base.html" %}

{% block title %} Students {% endblock %}
{% block body %}
<div class="container" style="text-align: center;">
    <h2 >Student List</h2><br>
    <h3>First Name Alphabetical Order</h3><br>
    <p><i class="fas fa-star-of-life star"></i> ID, Name, Course, Registered, Updated, Birthday <i class="fas fa-star-of-life star"></i></p>
        {% for student in students_list %}     
        <table class="table">
        <tbody>
            <tr>
            <td>#</td>
            <td>{{ student.id }}</td>
            <td>{{ student.student_name }}</td>
            <td>{{ student.course_name }}</td>
            <td>{{ student.created }}</td>
            <td>{{ student.updated }}</td>
            <td>{{ student.dob }}</td>
            </tr>
        </tbody>
        </table>
        {% endfor %}
    </table>
</div>
{% endblock %}

Prepare student list csv file

Test with dummy csv

Student names are output in alphabetical order.

●Four different texts are tied to each course with ForeignKey, so the text used is also shown.

Summary of This Topic

How to create objects in the Django database from a CSV file upload

Recommend

How to create a Django blog site

Recommend