管理员管理

创建数据库表

models.py

1
2
3
4
class Admin(models.Model):
    """管理员表"""
    username = models.CharField(verbose_name="用户名", max_length=32)
    password = models.CharField(verbose_name="密码", max_length=64)
1
在数据库生成<br>Tools->run manage.py task<br>执行命令
1
2
makemigrations
migrate

  

 数据库中插入一条数据

1
insert into  app01_admin(username,password) values("coco", "123");

  

 

增加管理员菜单

修改/app01/templates/layout.html

<ul class="nav navbar-nav">
<li><a href="/admin/list/">管理员账户管理</a></li>
<li><a href="/depart/list/">部门管理</a></li>
<li><a href="/user/list/">用户管理</a></li>
<li><a href="/prettynum/list/">靓号管理</a></li>
</ul>

  

 在views文件夹下新建admin.py,用于存放管理账户管理的视图函数

修改urls.py

1
2
3
4
5
6
7
#导入admin
from app01.views import depart, pretty, user, admin
#添加url
urlpatterns = [
    #管理员账户管理
    path('admin/list/', admin.admin_list),
]

 

 admin.py

from django.shortcuts import render
from app01 import models

def admin_list(request):
"""管理员列表"""
queryset = models.Admin.objects.all()

context = {
'queryset' : queryset
}
return render(request, 'admin_list.html', context)

 在templates文件夹创建admin_list.html

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
{% extends 'layout.html' %}
 
{% block content %}
    <div class="container">
        <div style="margin-bottom: 10px" class="clearfix">
            <a class="btn btn-success" href="#">
                <span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
                新建管理员
            </a>
            <div style="float: right; width: 300px;">
                <form>
                    <div class="input-group">
                        <input type="text" name="q" class="form-control" placeholder="Search for..."
                               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><!-- /input-group -->
                </form>
            </div>
        </div>
        <div class="panel panel-default">
            <!-- Default panel contents -->
            <div class="panel-heading">
                <span class="glyphicon glyphicon-th-list" aria-hidden="true"></span>
                管理员列表
            </div>
 
            <!-- Table -->
            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>ID</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 class="btn btn-primary btn-xs" href="#">编辑</a>
                            <a class="btn btn-danger btn-xs" href="#">删除</a>
                        </td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
{% endblock %}

  管理员列表就可以在前端展示出来了

 管理员列表添加分页

admin.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from django.shortcuts import render
 
from app01 import models
from app01.utils.pagination import Pagination
 
def admin_list(request):
    """管理员列表"""
    queryset = models.Admin.objects.all()
 
    page_object = Pagination(request, queryset)
    context = {
        'queryset' : page_object.page_queryset,
        'page_string': page_object.html()
    }
    return render(request, 'admin_list.html', context)

  

 admin_list.html

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
{% extends 'layout.html' %}
 
{% block content %}
    <div class="container">
        <div style="margin-bottom: 10px" class="clearfix">
            <a class="btn btn-success" href="#">
                <span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
                新建管理员
            </a>
            <div style="float: right; width: 300px;">
                <form>
                    <div class="input-group">
                        <input type="text" name="q" class="form-control" placeholder="Search for..."
                               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><!-- /input-group -->
                </form>
            </div>
        </div>
        <div class="panel panel-default">
            <!-- Default panel contents -->
            <div class="panel-heading">
                <span class="glyphicon glyphicon-th-list" aria-hidden="true"></span>
                管理员列表
            </div>
 
            <!-- Table -->
            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>ID</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 class="btn btn-primary btn-xs" href="#">编辑</a>
                            <a class="btn btn-danger btn-xs" href="#">删除</a>
                        </td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
        <ul class="pagination">
            {{ page_string }}
        </ul>
    </div>
{% endblock %}

 完成

 添加搜索功能

admin.py

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
from django.shortcuts import render
 
from app01 import models
from app01.utils.pagination import Pagination
 
def admin_list(request):
    """管理员列表"""
 
    #构造搜索
    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)

  

 

 admin_list.html

 新建管理员

admin_list.html

1
2
3
4
<a class="btn btn-success" href="/admin/add/">
    <span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
    新建管理员
</a>

 

 urls.py

1
path('admin/add/', admin.admin_add),

  修改/app01/views/admin.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from django import forms
from app01.utils.bootstrap import BootStrapModelForm
 
class AdminModelForm(BootStrapModelForm):
    confirm_password = forms.CharField(
        label="确认密码",
        #默认生成的input框为text框,想要密码不显示需要使用passwordInput框,定义widget插件实现
        widget=forms.PasswordInput
    )
 
    class Meta:
        model = models.Admin
        fields = ["username", "password", "confirm_password"]
        widgets = {
            "password": forms.PasswordInput
        }
 
def admin_add(request):
    """添加管理员"""
    form = AdminModelForm()
    return render(request, 'change.html', {'form': form, "title": "新建管理员"})

  

 

按照之前的套路,我应该会新建一个名为admin_add.html的HTML文件来展示添加界面
这次我们优化一下
不管是pretty_add.html或者user_add.html,除了标题不一样,其他的都是一样的
没有必要在创建一个单独的HTML页面,我们只需要在一个公共的HTML页面中传入各自的标题即可

新建zpp01/templates/change.html

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
{% 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">
                {#   novalidate去除浏览器的错误提示  #}
                <form method="post" novalidate>
                    {% csrf_token %}
 
                    {% for field in form %}
                        <div class="form-group">
                            <label>{{ field.label }}</label>
                            {{ field }}
                            {#  {{ field.errors }}错误信息是一个列表[错误1,错误2,错误3...], {{ field.errors.0 }}只取第一个错误1  #}
                            <span style="color: red;">{{ field.errors.0 }}</span>
                            {#   <input type="text" class="form-control" placeholder="姓名" name="user">  #}
                        </div>
                    {% endfor %}
 
                    <button type="submit" class="btn btn-primary">提 交</button>
                </form>
            </div>
        </div>
    </div>
{% endblock %}

  浏览器测试

 新建管理员页面点击提交,将数据保存到数据库

admin.py

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
from django import forms
from app01.utils.bootstrap import BootStrapModelForm
 
class AdminModelForm(BootStrapModelForm):
    confirm_password = forms.CharField(
        label="确认密码",
        #默认生成的input框为text框,想要密码不显示需要使用passwordInput框,定义widget插件实现
        widget=forms.PasswordInput
    )
 
    class Meta:
        model = models.Admin
        fields = ["username", "password", "confirm_password"]
        widgets = {
            "password": forms.PasswordInput
        }
 
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})

 

 

 

 存在问题:

密码跟确认密码输入不一致也能提交成功,需要添加校验,使密码、确认密码输入一致

修改app01/views/admin.py,增加钩子函数 clean_confirm_password

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<strong>#包的导入要按照内置包、第三方包、自己写的这种顺序导入,短的在前面</strong><br>from django import forms<br>#导入异常包
from django.core.exceptions import ValidationError
from app01.utils.bootstrap import BootStrapModelForm
 
class AdminModelForm(BootStrapModelForm):
    confirm_password = forms.CharField(
        label="确认密码",
        #默认生成的input框为text框,想要密码不显示需要使用passwordInput框,定义widget插件实现
        widget=forms.PasswordInput
    )
 
    class Meta:
        model = models.Admin
        fields = ["username", "password", "confirm_password"]
        widgets = {
            "password": forms.PasswordInput
        }
 
    #钩子函数
    def clean_confirm_password(self):
        password = self.cleaned_data.get("password")
        confirm = self.cleaned_data.get("confirm_password")
        if confirm != password:
            raise ValidationError("密码不一致,请重新输入。")      #返回什么,此字段以后保存到数据库就是什么<br>  <br>      return confirm

  

 

 可以发现,数据校验成功了
但是还有个问题,当我们点击保存后,密码和密码确认框中的数据清空了
这样不是太友好,因此我们需要添加一个属性

1
render_value=True

  

 浏览器测试,这样密码就不会清空了

现在又出现一个问题
直接将密码明文存储进数据库,很不安全
我们最好对其进行加密后,再进行保存 

密码采用md5加密

新建app01/utils/encrypt.py文件

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

  修改app01/views/admin.py

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
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="确认密码",
        #默认生成的input框为text框,想要密码不显示需要使用passwordInput框,定义widget插件实现
        widget=forms.PasswordInput(render_value=True)
    )
 
    class Meta:
        model = models.Admin
        fields = ["username", "password", "confirm_password"]
        widgets = {
            "password": forms.PasswordInput(render_value=True)
        }
 
    # clean_字段名
    def clean_password(self):
        pwd = self.cleaned_data.get("password")
        # return什么.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

  

 看看效果吧

 

添加管理员编辑页面

修改app01/templates/admin_list.html

1
<td>    <a class="btn btn-primary btn-xs" href="/admin/{{ obj.id }}/edit/">编辑</a><br>    <a class="btn btn-danger btn-xs" href="#">删除</a><br></td>

  

 修改myproject/myproject/urls.py

1
path('admin/<int:nid>/edit/', admin.admin_edit),

 添加一个公共的错误信息提示页面

在myprojrct/app01/templates/  新建 error.html

error.html

1
2
3
4
5
6
7
{% extends 'layout.html' %}
 
{% block content %}
    <div class="container">
        <div class="alert alert-danger" role="alert">{{ msg }}</div>
    </div>
{% endblock %}

  编写视图函数

修改myproject/app01/views/admin.py

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
class AdminEditModelForm(BootStrapModelForm):
    class Meta:
        model = models.Admin
        fields = ["username"]
 
def admin_edit(request,nid):
    """编辑管理员"""
 
    #如果数据存在返回一个对象,如果数据不存在,返回none
    row_object = models.Admin.objects.filter(id=nid).first()
    #判断nid是否存在
    if not row_object:
        return render(request,'error.html', {"msg": "数据不存在"})
    title = "编辑管理员"
 
    if request.method == "GET":
        # instance = row_object显示编辑框的默认值
        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})

 

 浏览器访问,修改cocococo1

 点击提交

 添加管理员删除

修改app01/templates/admin_list.html

1
2
3
4
<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>

修改myproject/myproject/urls.py

1
path('admin/<int:nid>/delete/', admin.admin_delete),

修改myproject/app01/views/admin.py

1
2
3
4
def admin_delete(request,nid):
    """删除管理员"""
    models.Admin.objects.filter(id=nid).delete()
    return redirect('/admin/list/')

  删除coco1

 完成

 

管理员重置密码

修改app01/templates/admin_list.html

1
<em id="__mceDel"><table class="table table-bordered"></em><em id="__mceDel">    <thead><br>    <tr><br>        <th>ID</th><br>        <th>用户名</th><br>        <th>密码</th><br>        <th>重置密码</th><br>        <th>操作</th><br>    </tr><br>    </thead><br>    <tbody><br>    {% for obj in queryset %}<br>        <tr><br>            <th>{{ obj.id }}</th><br>            <td>{{ obj.username }}</td><br>            <td>************</td><br>            <td><br>                <a href="/admin/{{ obj.id }}/reset/">重置密码</a><br>            </td><br>            <td><br>                <a class="btn btn-primary btn-xs" href="/admin/{{ obj.id }}/edit/">编辑</a><br>                <a class="btn btn-danger btn-xs" href="/admin/{{ obj.id }}/delete">删除</a><br>            </td><br>        </tr><br>    {% endfor %}<br>    </tbody><br></table></em>

 修改myproject/myproject/urls.py

1
path('admin/<int:nid>/reset/', admin.admin_reset),

修改myproject/app01/views/admin.py

 

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
class AdminResetModelForm(BootStrapModelForm):
    confirm_password = forms.CharField(
        label="确认密码",
        #默认生成的input框为text框,想要密码不显示需要使用passwordInput框,定义widget插件实现
        widget=forms.PasswordInput(render_value=True)
    )
    class Meta:
        model = models.Admin
        fields = ["password", "confirm_password"]
        widgets = {
            "password": forms.PasswordInput(render_value=True)
        }
    # clean_字段名
    def clean_password(self):
        pwd = self.cleaned_data.get("password")
        # return什么.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
 
def admin_reset(request,nid):
    """重置密码"""
    row_object = models.Admin.objects.filter(id=nid).first()
    if not row_object:
        return render('/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})

 添加功能:重置密码时不允许跟之前设置的密码一致 

修改myproject/app01/views/admin.py

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
class AdminResetModelForm(BootStrapModelForm):
    confirm_password = forms.CharField(
        label="确认密码",
        #默认生成的input框为text框,想要密码不显示需要使用passwordInput框,定义widget插件实现
        widget=forms.PasswordInput(render_value=True)
    )
    class Meta:
        model = models.Admin
        fields = ["password", "confirm_password"]
        widgets = {
            "password": forms.PasswordInput(render_value=True)
        }
    # clean_字段名
    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什么.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

 

 完成

 

 

 

  

  

  

 

 

 

 

 

1
<br><br>
posted @   可可eleven  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示