• 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
  • 相关阅读:
    PreScan快速入门到精通第二十三讲2D车辆动力学模型
    什么是智慧型人格?智慧型性格的优缺点和职业规划
    微服务项目实战-黑马头条(三):APP端文章详情
    Codeforces Round 908
    Decorator 装饰者模式简介与 C# 示例【结构型4】【设计模式来了_9】
    如何提升新闻公关发稿的效果?
    使用FineBI,轻松搞定汽车金融公司风险指标分析!
    (十七)VBA常用基础知识:读写text文件
    Apache Paimon Flink引擎解析
    常见的排序算法及时间空间复杂度
  • 原文地址:https://blog.csdn.net/u010520724/article/details/126883529