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
- views.py
- urls.py list, import, and export
- forms.py: Create forms for import
- base.html: Common settings and menu bar
- student_import.html: Create template for import
- student_list.html: Create student list
- Prepare student list csv file
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
{% 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