Django开发一个简易学生管理系统

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>
相关推荐
苏三说技术1 小时前
Claude Code从失控到起飞,只用了这些技巧
后端
aqi001 小时前
15天学会AI应用开发(七)有了大模型为什么还要引入RAG
人工智能·python·大模型·ai编程·ai应用
长栎2 小时前
写 for 循环写了十年,你却从没用过迭代器模式最狠的那一面
后端
LiaCode2 小时前
Redis 在生产项目的使用
前端·后端
用户559822481222 小时前
Docker Compose Down 导致容器数据误删——ext4 日志恢复全记录
后端
LiaCode2 小时前
一天学完 redis 的爽翻版核心知识总结
前端·后端
大刚测试开发实战2 小时前
如何内网穿透访问本地私有化部署的TestHub
前端·后端·github
xiaodaoluanzha3 小时前
迄今為止,最簡單的編程語言 Nolang
前端·后端
Csvn3 小时前
Docker 容器管理入门 — 从镜像到容器编排
后端