• Django系列13-员工管理系统实战--管理员


    一. 管理员管理:表结构设计

    image.png

    根据表结构的需求,在models.py中创建类(由类生成数据库中的表)。

    class Admin(models.Model):
        """ 管理员 """
        username = models.CharField(verbose_name="用户名", max_length=32)
        password = models.CharField(verbose_name="密码", max_length=64)
    
        def __str__(self):
            return self.username
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Django命令生成库表

    python manage.py makemigrations 
    python manage.py migrate
    
    • 1
    • 2

    二. URL调整

    新增对应的 增删改查对应的URL,如下图:

    对比其它的页面,多了一个reset重置密码的url
    image.png

        # 管理员的管理
        path('admin/list/', admin.admin_list),
        path('admin/add/', admin.admin_add),
        path('admin//edit/', admin.admin_edit),
        path('admin//delete/', admin.admin_delete),
        path('admin//reset/', admin.admin_reset),
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    三. 后端功能实现

    3.1 加密公共类实现

    因为密码比较敏感,页面显示以及存入数据库的时候,都需要做处理,存入数据库需要进行md5加密

    encrypt.py

    from django.conf import settings
    import hashlib
    
    
    def md5(data_string):
        obj = hashlib.md5(settings.SECRET_KEY.encode('utf-8'))
        obj.update(data_string.encode('utf-8'))
        return obj.hexdigest()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.1 增删改查逻辑实现

    admin.py

    from django.shortcuts import render, redirect
    
    from app01 import models
    from app01.utils.pagination import Pagination
    
    from django import forms
    from django.core.exceptions import ValidationError
    from app01.utils.bootstrap import BootStrapModelForm
    from app01.utils.encrypt import md5
    
    
    class AdminModelForm(BootStrapModelForm):
        confirm_password = forms.CharField(
            label="确认密码",
            widget=forms.PasswordInput(render_value=True)
        )
    
        class Meta:
            model = models.Admin
            fields = ["username", 'password', "confirm_password"]
            widgets = {
                "password": forms.PasswordInput(render_value=True)
            }
    
        def clean_password(self):
            pwd = self.cleaned_data.get("password")
            return md5(pwd)
    
        def clean_confirm_password(self):
            pwd = self.cleaned_data.get("password")
            confirm = md5(self.cleaned_data.get("confirm_password"))
            if confirm != pwd:
                raise ValidationError("密码不一致")
            # 返回什么,此字段以后保存到数据库就是什么。
            return confirm
    
    
    class AdminEditModelForm(BootStrapModelForm):
        class Meta:
            model = models.Admin
            fields = ['username']
    
    
    class AdminResetModelForm(BootStrapModelForm):
        confirm_password = forms.CharField(
            label="确认密码",
            widget=forms.PasswordInput(render_value=True)
        )
    
        class Meta:
            model = models.Admin
            fields = ['password', 'confirm_password']
            widgets = {
                "password": forms.PasswordInput(render_value=True)
            }
    
        def clean_password(self):
            pwd = self.cleaned_data.get("password")
            md5_pwd = md5(pwd)
    
            # 去数据库校验当前密码和新输入的密码是否一致
            exists = models.Admin.objects.filter(id=self.instance.pk, password=md5_pwd).exists()
            if exists:
                raise ValidationError("不能与以前的密码相同")
    
            return md5_pwd
    
        def clean_confirm_password(self):
            pwd = self.cleaned_data.get("password")
            confirm = md5(self.cleaned_data.get("confirm_password"))
            if confirm != pwd:
                raise ValidationError("密码不一致")
            # 返回什么,此字段以后保存到数据库就是什么。
            return confirm
    
    
    def admin_list(request):
        """ 管理员列表 """
    
        # info_dict = request.session["info"]
        # print(info_dict["id"])
        # print(info_dict['name'])
    
        # 构造搜索
        data_dict = {}
        search_data = request.GET.get('q', "")
        if search_data:
            data_dict["username__contains"] = search_data
    
        # 根据搜索条件去数据库获取
        queryset = models.Admin.objects.filter(**data_dict)
    
        # 分页
        page_object = Pagination(request, queryset)
        context = {
            'queryset': page_object.page_queryset,
            'page_string': page_object.html(),
            "search_data": search_data
        }
        return render(request, 'admin_list.html', context)
    
    
    def admin_add(request):
        """ 添加管理员 """
        title = "新建管理员"
        if request.method == "GET":
            form = AdminModelForm()
            return render(request, 'change.html', {'form': form, "title": title})
        form = AdminModelForm(data=request.POST)
        if form.is_valid():
            form.save()
            return redirect('/admin/list/')
    
        return render(request, 'change.html', {'form': form, "title": title})
    
    
    def admin_edit(request, nid):
        """ 编辑管理员 """
        # 对象 / None
        row_object = models.Admin.objects.filter(id=nid).first()
        if not row_object:
            # return render(request, 'error.html', {"msg": "数据不存在"})
            return redirect('/admin/list/')
    
        title = "编辑管理员"
        if request.method == "GET":
            form = AdminEditModelForm(instance=row_object)
            return render(request, 'change.html', {"form": form, "title": title})
    
        form = AdminEditModelForm(data=request.POST, instance=row_object)
        if form.is_valid():
            form.save()
            return redirect('/admin/list/')
        return render(request, 'change.html', {"form": form, "title": title})
    
    
    def admin_delete(request, nid):
        """ 删除管理员 """
        models.Admin.objects.filter(id=nid).delete()
        return redirect('/admin/list/')
    
    
    def admin_reset(request, nid):
        """ 重置密码 """
        # 对象 / None
        row_object = models.Admin.objects.filter(id=nid).first()
        if not row_object:
            return redirect('/admin/list/')
    
        title = "重置密码 - {}".format(row_object.username)
    
        if request.method == "GET":
            form = AdminResetModelForm()
            return render(request, 'change.html', {"form": form, "title": title})
    
        form = AdminResetModelForm(data=request.POST, instance=row_object)
        if form.is_valid():
            form.save()
            return redirect('/admin/list/')
        return render(request, 'change.html', {"form": form, "title": title})
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161

    四. 前端页面

    4.1 模板页面

    layout.html
    image.png

    4.2 管理员列表页面

    admin_list.html

    {% extends 'layout.html' %}
    
    {% block content %}
        <div class="container">
            <div style="margin-bottom: 10px" class="clearfix">
                <a class="btn btn-success" href="/admin/add/">
                    <span class="glyphicon glyphicon-plus-sign" aria-hidden="true">span>
                    新建管理员
                a>
    
                <div style="float: right;width: 300px;">
                    <form method="get">
                        <div class="input-group">
                            <input type="text" name="q" class="form-control" placeholder="关键字"
                                   value="{{ search_data }}">
                            <span class="input-group-btn">
                            <button class="btn btn-default" type="submit">
                                <span class="glyphicon glyphicon-search" aria-hidden="true">span>
                            button>
                          span>
                        div>
                    form>
                div>
    
            div>
            <div class="panel panel-default">
                
                <div class="panel-heading">
                    <span class="glyphicon glyphicon-th-list" aria-hidden="true">span>
                    管理员列表
                div>
    
                
                <table class="table table-bordered">
                    <thead>
                    <tr>
                        <th>IDth>
                        <th>用户名th>
                        <th>密码th>
                        <th>重置密码th>
                        <th>操作th>
                    tr>
                    thead>
                    <tbody>
                    {% for obj in queryset %}
                        <tr>
                            <th>{{ obj.id }}th>
                            <td>{{ obj.username }}td>
                            <td>*******td>
                            <td>
                                <a href="/admin/{{ obj.id }}/reset/">重置密码a>
                            td>
                            <td>
                                <a class="btn btn-primary btn-xs" href="/admin/{{ obj.id }}/edit/">编辑a>
                                <a class="btn btn-danger btn-xs" href="/admin/{{ obj.id }}/delete/">删除a>
                            td>
                        tr>
                    {% endfor %}
    
                    tbody>
                table>
            div>
    
            <ul class="pagination">
                {{ page_string }}
            ul>
        div>
    {% endblock %}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    4.3 管理员数据修改页面

    管理员页面涉及 新增、修改、重置密码
    我们此时可以使用同一个页面,针对性的隐藏部分即可

    change.html

    {% extends 'layout.html' %}
    
    
    {% block content %}
    
        <div class="container">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title"> {{ title }} h3>
                div>
                <div class="panel-body">
                    <form method="post" novalidate>
                        {% csrf_token %}
    
                        {% for field in form %}
                            <div class="form-group">
                                <label>{{ field.label }}label>
                                {{ field }}
                                <span style="color: red;">{{ field.errors.0 }}span>
                            div>
                        {% endfor %}
    
                        <button type="submit" class="btn btn-primary">提 交button>
                    form>
                div>
            div>
        div>
    
    {% endblock %}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    五. 页面测试

    管理员列表页面:
    image.png

    新增管理员页面:
    image.png

    编辑页面:
    image.png

    重置密码页面:
    image.png

    参考:

    1. https://www.bilibili.com/video/BV1NL41157ph
  • 相关阅读:
    第十天 移动端网页特效
    【LeetCode】36、有效的数独
    [NOIP2006 提高组] 作业调度方案
    linux常用命令(2):tar命令(压缩文件/解压缩文件)
    leetcode_1339. 分裂二叉树的最大乘积
    【技术积累】Python基础知识【第二版】
    如果让我设计一套,TPS百万级API网关!
    【AI学习笔记】TensorFlow 与 Keras的安装(Windows Anaconda 虚拟环境版)
    Codeforces Round 900 (Div. 3) 题解 | JorbanS
    数学建模学习(73):用Python敏感性分析,如此轻松简单
  • 原文地址:https://blog.csdn.net/u010520724/article/details/126883529