1. 创建admin表
| |
| |
| from django.db import models |
| |
| 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 |
| |
2. 创建路由(url)
| |
| |
| from bbc_list.views import login, home_page, order, phone, admin |
| urlpatterns = [ |
| |
| path("admin/list/", admin.admin_list), |
| path("admin/add/", admin.admin_add), |
| path("admin/<int:nid>/update/", admin.admin_update), |
| path("admin/<int:nid>/delete/", admin.admin_delete), |
| path('admin/<int:nid>/reset/', admin.admin_reset),] |
| |
3. 创建视图函数
| |
| |
| from django.core.exceptions import ValidationError |
| from django.shortcuts import render, redirect |
| |
| from bbc_list import models |
| from bbc_list.utils.pagemtion import Pagination |
| from bbc_list.utils.md5_data import md5 |
| |
| |
| 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) |
| |
| |
| from bbc_list.utils.bootstrap import BootStrapModelForm |
| from django import forms |
| |
| |
| class AdminModelForm(BootStrapModelForm): |
| """添加一个确认密码的输入框,这个字段在数据库里是没有的""" |
| confire_password = forms.CharField(label="确认密码", |
| |
| widget=forms.PasswordInput(render_value=True) |
| ) |
| |
| class Meta: |
| model = models.Admin |
| fields = ["username", "password", "confire_password"] |
| widgets = { |
| "password": forms.PasswordInput(render_value=True) |
| } |
| |
| def clean_password(self): |
| """获取密码加密""" |
| pwd = self.cleaned_data.get("password") |
| return md5(pwd) |
| |
| def clean_confire_password(self): |
| """钩子方法,获取密码和确认密码""" |
| |
| pwd = self.cleaned_data.get("password") |
| confire = md5(self.cleaned_data.get("confire_password")) |
| if confire != pwd: |
| raise ValidationError("密码不一致") |
| |
| return confire |
| |
| |
| 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}) |
| |
| |
| class AdminUpdate(BootStrapModelForm): |
| class Meta: |
| model = models.Admin |
| fields = ["username"] |
| |
| |
| def admin_update(request, nid): |
| """编辑""" |
| |
| |
| row_object = models.Admin.objects.filter(id=nid).first() |
| if not row_object: |
| |
| |
| |
| |
| return redirect("/admin/list/") |
| title = "编辑管理员" |
| |
| if request.method == "GET": |
| form = AdminUpdate(instance=row_object) |
| return render(request, "change.html", {"form": form, "title": title}) |
| |
| form = AdminUpdate(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(reuquest, nid): |
| """删除""" |
| models.Admin.objects.filter(id=nid).delete() |
| return redirect("/admin/list/") |
| |
| |
| class AdminReset(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_data = md5(pwd) |
| |
| |
| |
| exists = models.Admin.objects.filter(id=self.instance.pk, password=md5_data).exists() |
| if exists: |
| raise ValidationError("密码不能与之前相同") |
| return md5_data |
| |
| 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 redirect("/admin/list/") |
| |
| title = "重置密码-{}".format(row_object.username) |
| |
| if request.method == "GET": |
| form = AdminReset() |
| return render(request, "change.html", {"form": form, "title": title}) |
| |
| form = AdminReset(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}) |
| |
4. 创建html页面
| # templates-->admin_list.html |
| |
| {% extends 'one.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" 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> |
| |
| <a class="btn btn-success" href="/phone/add/"> |
| <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> |
| 新建手机号ModelForm</a> |
| </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>ID</th> |
| <th>用户名</th> |
| <th>密码</th> |
| <th>重置密码</th> |
| <th>操作</th> |
| </tr> |
| </thead> |
| <tbody> |
| {% for obj in queryset %} |
| <tr> |
| <th>{{ obj.id }}</th> |
| <th>{{ obj.username }}</th> |
| <th>*******</th> |
| <td> |
| <a href="/admin/{{ obj.id }}/reset/">重置密码</a> |
| </td> |
| <td> |
| <a class="btn btn-primary btn-xs" href="/admin/{{ obj.id }}/update/">编辑</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 %} |
| |
| # templates-->change.html |
| |
| {% extends 'one.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 %} |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人