05 学生管理系统
定义模型
python
from django.db import models
class Student(models.Model):
gender_choices = (
("男", "男"),
("女", "女"),
("保密", "保密"),
)
name = models.CharField(db_index=True, max_length=36, verbose_name="姓名")
age = models.SmallIntegerField(verbose_name="年龄")
gender = models.CharField(verbose_name="性别", choices=gender_choices, max_length=6)
birthday = models.DateField(verbose_name="生日")
def __str__(self):
return self.name
class Meta:
db_table = 'student'
verbose_name = "学生"
verbose_name_plural = verbose_name
迁移数据:
bash
python manage.py makemigrations
python manage.py migrate
后台管理
创建一个超级用户:
bash
python manage.py createsuperuser
将模型注册到后台:
python
from django.contrib import admin
from . import models
@admin.register(models.Student)
class StudentAdmin(admin.ModelAdmin):
list_display = ('name', 'age', 'gender', 'birthday')
search_fields = ('name', 'age', 'gender', 'birthday')
list_filter = ('age', 'gender', 'birthday')
启动服务,访问后台,然后添加几个学生,至少添加三个。
渲染学生列表
定义视图函数:
python
from django.shortcuts import render
from . import models
def student_list(request):
context = {}
students = models.Student.objects.all()
context['students'] = students
return render(request, "student/list.html", context)
定义路由:
python
from django.urls import path
from . import views
app_name = 'index'
urlpatterns = [
path("student/list/", views.student_list, name="student_list"),
]
定义模板:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>学生列表</h1>
<table>
<tr>
<th>#</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>生日</th>
</tr>
{% for student in students %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ student.name }}</td>
<td>{{ student.age }}</td>
<td>{{ student.gender }}</td>
<td>{{ student.birthday }}</td>
</tr>
{% empty %}
<tr>
<td colspan="5">暂无数据</td>
</tr>
{% endfor %}
</table>
</body>
</html>
此时,启动服务,访问:http://localhost:8001/student/list/
添加学生
这次数据是从前端到后端的,所以我们先写模板:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>添加学生</h1>
<form action="{% url 'index:student_add' %}" method="post">
{% csrf_token %}
<div>
<label for="name">姓名</label>
<input type="text" id="name" name="name">
</div>
<div>
<label for="age">年龄</label>
<input type="number" id="age" name="age">
</div>
<div>
<label for="birthday">生日</label>
<input type="date" id="birthday" name="birthday">
</div>
<div>
<label for="gender">性别</label>
<select id="gender" name="gender">
<option value="">请选择</option>
<option value="男">男</option>
<option value="女">女</option>
<option value="保密">保密</option>
</select>
</div>
<div>
<button type="submit">提交</button>
</div>
</form>
</body>
</html>
接着,我们再定义路由:
python
from django.urls import path
from . import views
app_name = 'index'
urlpatterns = [
path("student/list/", views.student_list, name="student_list"),
path("student/add/", views.student_add, name="student_add"),
]
最后,我们再添加视图:
python
import datetime
from django.shortcuts import render, redirect
from . import models
def student_list(request):
context = {}
students = models.Student.objects.all()
context['students'] = students
return render(request, "student/list.html", context)
def student_add(request):
context = {}
if request.method == "POST":
# 获取参数
name = request.POST.get("name")
age = request.POST.get("age")
gender = request.POST.get("gender")
birthday = request.POST.get("birthday")
print(name, age, gender, birthday)
# 执行添加
student = models.Student(name=name, age=age, gender=gender, birthday=birthday)
student.save()
return redirect("index:student_list")
return render(request, "student/add.html", context)
修改学生信息
首先,我们需要修改一下学生列表对应的模板,在表格的后面新增一个操作列。需要注意的是,在编辑的href属性里面,我们将学生ID作为查询参数传递给了后端。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>学生列表</h1>
<table>
<tr>
<th>#</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>生日</th>
<th>操作</th>
</tr>
{% for student in students %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ student.name }}</td>
<td>{{ student.age }}</td>
<td>{{ student.gender }}</td>
<td>{{ student.birthday }}</td>
<td>
<a href="{% url 'index:student_edit' %}?id={{ student.id }}">编辑</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="6">暂无数据</td>
</tr>
{% endfor %}
</table>
</body>
</html>
接着,我们定义路由:
python
from django.urls import path
from . import views
app_name = 'index'
urlpatterns = [
path("student/list/", views.student_list, name="student_list"),
path("student/add/", views.student_add, name="student_add"),
path("student/edit/", views.student_edit, name="student_edit"),
]
然后我们再添加视图函数。视图函数稍微复杂了一点,包含GET和POST两种处理逻辑。我们先根据学生ID查询学生信息,如果是GET请求,就将学生信息传递给前端,然前端渲染要修改的学生信息。如果是POST请求,我们就获取用户要修改的学生信息,进行替换,然后保存到数据库。最后重定向到学生列表页面。
需要注意的是,我们同时又传递了id和genders两个属于,便于渲染。
python
def student_edit(request):
context = {}
# 查询学生信息
uid = request.GET.get("id")
context["id"] = uid
context["genders"] = ["男", "女", "保密"]
student = models.Student.objects.filter(pk=uid).first()
print(uid, student)
if request.method == "POST":
# 获取参数
name = request.POST.get("name")
age = request.POST.get("age")
gender = request.POST.get("gender")
birthday = request.POST.get("birthday")
print(name, age, gender, birthday)
# 执行修改
if name:
student.name = name
if age:
student.age = age
if gender:
student.gender = gender
if birthday:
student.birthday = birthday
student.save()
return redirect("index:student_list")
context["student"] = student
return render(request, "student/edit.html", context)
然后,我们再添加修改学生的模板。这个模板也稍微有点复杂,一个是性别的渲染,利用了for循环渲染和if条件渲染两种灵活的语法,用于标识被选中的值。另一个是生日的渲染,生日默认会渲染为"2024年1月1日"这样的格式,inpute:date标签无法渲染,需要手动转换为"2024-1-1"这样的格式。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>添加学生</h1>
<form action="{% url 'index:student_edit' %}?id={{ id }}" method="post">
{% csrf_token %}
<div>
<label for="name">姓名</label>
<input type="text" id="name" name="name" value="{{ student.name }}">
</div>
<div>
<label for="age">年龄</label>
<input type="number" id="age" name="age" value="{{ student.age }}">
</div>
<div>
<label for="birthday">生日</label>
<input type="date" id="birthday" name="birthday" value="{{ student.birthday | date:"Y-m-d"}}">
</div>
<div>
<label for="gender">性别</label>
<select id="gender" name="gender">
{% for gender in genders %}
{% if student.gender == gender %}
<option value="{{ gender }}" selected>{{ gender }}</option>
{% else %}
<option value="{{ gender }}">{{ gender }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<div>
<button type="submit">提交</button>
</div>
</form>
</body>
</html>