这是Django框架从入门到精通(第四章用户管理)内附源码
文章目录
- 前言
-
目录
前言:
经过前期的学习,我们掌握了最基本的用法,这期将把后面的知识点全部使用,只给大家简单说一下,具体知识点还是按流程来,给大家看一下成品:
这就是我们学习完之后的知识点,能做出来的,这个页面有些不太好看,我们可以用css来修饰,给大家看我的源码:
-
建立数据库,并创建表:
from django.db import models
# 部门类
class Department(models.Model):
title = models.CharField(verbose_name='标题', max_length=32)
def __str__(self):
return self.title
# 员工类
class UserInfo(models.Model):
name = models.CharField(verbose_name='姓名', max_length=16)
password = models.CharField(verbose_name='密码', max_length=64)
age = models.IntegerField(verbose_name='年龄')
account = models.DecimalField(verbose_name='余额', max_digits=10, decimal_places=2, default=0)
create_time = models.DateField(verbose_name='入职时间')
# to与哪张表关联
# to_field 表中的哪一列关联
# Django 自动后面生成_id
# 若部门删除
# 1)级联删除 on_delete=models.CASCADE
# 2) 置空 null=ture black=ture
depart = models.ForeignKey(verbose_name="部门", to="Department", to_field="id", on_delete=models.CASCADE)
gender_choices = (
(1, "男"),
(2, "女"),
)
gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices)
# 管理员类
class Admin(models.Model):
username = models.CharField(verbose_name="用户名", max_length=32)
password = models.CharField(verbose_name="密码", max_length=64)
这里涉及到了主键约束,和级联删除,代码中有注释
-
建立url:
urlpatterns = [
# path('admin/', admin.site.urls),
path('depart/list/', views.depart_list),
path('uesr/model/form/add/', views.user_model_form_add),
path('main/page/', views.main_page),
# 将id传递
path('user/<int:nid>/edit/', views.user_edit),
path('user/<int:nid>/data/', views.user_data),
path('admin/list/', views.admin_list),
path('admin/add/', views.admin_add),
path('admin/<int:nid>/edit/', views.admin_edit),
path('admin/<int:nid>/delet/', views.admin_delet),
path('admin/<int:nid>/edit/password/', views.admin_edit_password),
path('admin/login/', views.login),
path('admin/logout/', views.logout)
]
这些都是url与函数的对应关系。
-
主函数views.py
首先给大家看我我们要导入的模块
# 导入forms模块
from django import forms
# 导入正则表达式
from django.core.validators import RegexValidator
# 导入自己设置报错模块
from django.core.exceptions import ValidationError
# 导入django自带的md5加密的盐
from django.conf import settings
# 导入中间件
from django.utils.deprecation import MiddlewareMixin
-
定义md5方法将数据库加密
# 运用md5将数据库密码加密
def md5(data_string):
obj = hashlib.md5(settings.SECRET_KEY.encode('utf-8'))
obj.update(data_string.encode('utf-8'))
return obj.hexdigest()
-
定义bootstrap类
# 定义bootstrap类
class BootStrapModelForm(forms.ModelForm):
# 定义init方法
def __init__(self, *args, **kwargs):
# 执行父类的init方法
super().__init__(*args, **kwargs)
# 循环modelform每一个字段,设置字段的插件
for name, field in self.fields.items():
if field.widget.attrs:
# 若字典内有值
field.widget.attrs["class"] = "form-control"
else:
# 若字典内有值
field.widget.attrs = {"class": "form-control"}
-
定义中间件
# 定义中间件
class AuthMiddleWare(MiddlewareMixin):
def process_request(self, request):
# 排除不需要登陆就可以访问的页面
if request.path_info == "/admin/login/":
return
# 读取访问用户的session信息
info_dict = request.session.get("info")
if info_dict:
return
# 若没登陆去登录页面
return redirect('/admin/login/')
-
定义modelform类并继承bootstrap类
# 继承bootstrap类
class UserModelForm(BootStrapModelForm):
name = forms.CharField(min_length=2,
label="用户名",
# validators=正则表达式(方式一)
# validators=RegexValidator())
)
# 正则表达式
RegexValidator()
class Meta:
model = models.UserInfo
fields = ["name", "password", "age", "account", "create_time", "depart", "gender"]
# 方式2(定义钩子方法)
def clean_name(self):
txt_name = self.cleaned_data["name"]
# 钩子方法校验
if len(txt_name) > 10:
raise ValidationError("格式错误")
# 验证通过返回(必须这样写)
return txt_name
-
定义管理员modelform类,并继承bootstrap类
# 定义新的modelform管理员密码类
# 并继承Bootstrap父类
class AdminEditPasswordModelForm(BootStrapModelForm):
confirm_password = forms.CharField(label="确认密码", widget=forms.PasswordInput(render_value=True))
class Meta:
model = models.Admin
fields = ['password', 'confirm_password']
def clean_password(self):
# 获得用户输入的密码
pwd = self.cleaned_data.get("password")
# 用md5将数据加密
md5_pwd = md5(pwd)
# 在数据库中搜索id,password
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 main_page(request):
# 去数据库中拿到所有信息
model_user_info = models.UserInfo.objects.all()
# 建数据库中信息传入前端
return render(request, 'main_page.html', {"objects": model_user_info})
# 员工存储页面
def user_model_form_add(request):
# 用户访问get方式
if request.method == "GET":
form = UserModelForm()
return render(request, 'user_model_form_add.html', {"form": form})
# 用户post请求提交数据,校验数据
form = UserModelForm(data=request.POST)
if form.is_valid():
# 校验正确存入库
form.save()
return redirect('/main/page/')
else:
return render(request, 'user_model_form_add.html', {"form": form})
# 编辑员工信息
def user_edit(request, nid):
row_object = models.UserInfo.objects.filter(id=nid).first()
if request.method == "GET":
form = UserModelForm(instance=row_object)
return render(request, 'user_edit.html', {"form": form})
elif request.method == "POST":
form = UserModelForm(data=request.POST, instance=row_object)
if form.is_valid():
form.save()
# 重定向回主页面
return redirect('/main/page')
return render(request, 'user_edit.html', {"form": form})
# 删除员工信息
def user_data(request, nid):
models.UserInfo.objects.filter(id=nid).delete()
# 删除后重定向
return redirect('/main/page')
-
管理员类增删改查
# 管理员列表
def admin_list(request):
queryset = models.Admin.objects.all()
return render(request, 'admin_list.html', {"queryset": queryset})
# 新建管理员
def admin_add(request):
title = "新建管理员"
if request.method == "GET":
form = AdminModelForm()
return render(request, 'admin_add.html', {'form': form, 'title': title})
form = AdminModelForm(data=request.POST)
if form.is_valid():
form.save()
return redirect('/admin/list/')
return render(request, 'admin_add.html', {'form': form, "title": title})
# 编辑管理员
def admin_edit(request, nid):
title = "管理员编辑表"
row_object = models.Admin.objects.filter(id=nid).first()
if not row_object:
return redirect('/admin/list/')
# get请求
if request.method == 'GET':
form = AdminModelForm(instance=row_object)
return render(request, 'admin_edit.html', {"title": title, "queryset": form})
# post请求保存到数据库
elif request.method == "POST":
form = AdminModelForm(data=request.POST, instance=row_object)
if form.is_valid():
# 校验正确保存到数据库
form.save()
return redirect('/admin/list/')
return render(request, 'admin_edit.html', {"queryset": form})
# 删除管理员
def admin_delet(request, nid):
models.Admin.objects.filter(id=nid).delete()
# 重定向回列表页面
return redirect('/admin/list/')
# 重置密码
def admin_edit_password(request, nid):
row_object = models.Admin.objects.filter(id=nid).first()
if not list:
return redirect('/admin/list/')
title = '重置管理员密码----{}'.format(row_object.username)
if request.method == "GET":
form = AdminEditPasswordModelForm(instance=row_object)
return render(request, 'admin_edit_password.html', {"queryset": form, "title": title})
elif request.method == "POST":
form = AdminEditPasswordModelForm(data=request.POST, instance=row_object)
if form.is_valid():
form.save()
return redirect('/admin/list/')
return render(request, 'admin_edit_password.html', {"queryset": form, "title": title})
# 管理员登录类
class LoginForm(forms.Form):
username = forms.CharField(label="用户名", widget=forms.TextInput, required=True)
password = forms.CharField(label="密码", widget=forms.PasswordInput(render_value=True), required=True)
def clean_password(self):
pwd = self.cleaned_data.get("password")
return md5(pwd)
# 管理员登录界面
def login(request):
if request.method == "GET":
form = LoginForm()
return render(request, 'login.html', {"form": form})
elif request.method == "POST":
form = LoginForm(data=request.POST)
if form.is_valid():
# 去数据库校验账号和密码,获取用户对象
admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
if not admin_object:
# 主动添加错误
form.add_error("password", "用户名或密码不正确")
return render(request, 'login.html', {"form": form})
# 进行cookie认证和session
# 若正确,网站生成随机字符串,写到用户的浏览器cookie中,再写到session中
else:
# 写入session中
request.session["info"] = {"id": admin_object.id, "name": admin_object.username}
# 登录成功进行重定向
return redirect('/main/page/')
return render(request, 'login.html', {"form": form})
# 注销登录
def logout(request):
request.session.clear()
return redirect('/admin/login')
这就是views的所有代码,给大家看一下前端的代码
首先:
-
管理员添加html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="container">
<div class="panel panel-default">
<div>
<h1> {{ title }}注册表</h1>
</div>
<form method="post" novalidate>
<fieldset>
{% csrf_token %}
{% for iteam in form %}
<div class="form-group">
{{ iteam.label }}: {{ iteam }}<br><br>
<span style="color: red"> {{ iteam.errors.0 }}</span>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">
提交
</button>
</fieldset>
</form>
</div>
</div>
</body>
</html>
-
修改管理员信息html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="container">
<div class="panel panel-default">
<div>
<h1> {{ title }}</h1>
</div>
<form method="post" novalidate>
<fieldset>
{% csrf_token %}
{% for iteam in queryset %}
<div class="form-group">
{{ iteam.label }}: {{ iteam }}<br><br>
<span style="color: red"> {{ iteam.errors.0 }}</span>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">
提交
</button>
</fieldset>
</form>
</div>
</div>
</body>
</html>
修改管理员密码html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="container">
<div class="panel panel-default">
<div>
<h1> {{ title }}</h1>
</div>
<form method="post" novalidate>
<fieldset>
{% csrf_token %}
{% for iteam in queryset %}
<div class="form-group">
{{ iteam.label }}: {{ iteam }}<br><br>
<span style="color: red"> {{ iteam.errors.0 }}</span>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">
提交
</button>
</fieldset>
</form>
</div>
</div>
</body>
</html>
-
管理员页面html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a class="btn btn-success" href="/admin/add/">新建管理员</a>
<table border="1" width="900px"> <!--border:表格边框,width:表格宽度-->
<caption>管理员中心</caption> <!--标题标签,居中显示,仅有一个标题-->
<tr>
<th>id</th>
<th>姓名</th> <!--th标签:表格头,内容居中,加粗显示-->
<th>密码</th>
<th>密码操作</th>
<th>操作</th>
</tr>
{% for obj in queryset %}
<tr>
<td> {{ obj.id }}</td>
<td>{{ obj.username }}</td> <!--td标签:普通表格,内容左对齐-->
<td>*********</td>
<td><a class="btn btn-success" href="/admin/{{ obj.id }}/edit/password/">重置密码</a></td>
<td>
<a class="btn-primary btn-xs" href="/admin/{{ obj.id }}/edit/">编辑</a>
<a class="btn-danger btn-ns" href="/admin/{{ obj.id }}/delet/">删除</a>
{% endfor %}
</td>
</tr>
</table>
</body>
</html>
-
登录页面的html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
background: url('https://cdn.pixabay.com/photo/2018/08/14/13/23/ocean-3605547_1280.jpg') no-repeat;
background-size: 100% 130%;
}
#login_box {
width: 20%;
height: 400px;
background-color: #00000060;
margin: auto;
margin-top: 10%;
text-align: center;
border-radius: 10px;
padding: 50px 50px;
}
h2 {
color: #ffffff90;
margin-top: 5%;
}
#input-box {
margin-top: 5%;
}
span {
color: #fff;
}
input {
border: 0;
width: 60%;
font-size: 30px;
color: #fff;
background: transparent;
border-bottom: 6px solid #fff;
padding: 5px 10px;
outline: none;
margin-top: 10px;
}
button {
margin-top: 50px;
width: 60%;
height: 30px;
border-radius: 10px;
border: 0;
color: #fff;
text-align: center;
line-height: 30px;
font-size: 15px;
background-image: linear-gradient(to right, #30cfd0, #330867);
}
#sign_up {
margin-top: 45%;
margin-left: 60%;
}
a {
color: #b94648;
}
</style>
</head>
<body>
<form method="post" novalidate>
{% csrf_token %}
<div id="login_box">
<h2>管理员登录</h2>
<div id="input_box">
{{ form.username.label }}:{{ form.username }}<br><br>
<span style="color: red">{{ form.username.errors.0 }}</span>
</div>
<div class="input_box">
{{ form.password.label }}:{{ form.password }}<br><br>
<span style="color: red">{{ form.password.errors.0 }}</span>
</div>
<button type="submit">登录</button>
<br>
</div>
</form>
</body>
</html>
-
部门添加页面html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
{% csrf_token %}
<label><input class="text" name="title" value="请添加部门"/> 部门名称</label>
<button type="submit" class="btn btn-primary">
提交
</button>
</form>
</body>
</html>
-
员工主页面html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
li {
display: inline;
list-style: none;
margin: 0 20px;
}
</style>
</head>
<body>
<nav class="pageNav">
<ul class="list">
<li><a href="/main/page/" target="_blank"><span>员工管理</span></a></li>
<li><a href="/admin/list/" target="_blank"><span>管理员管理</span></a></li>
<li><a href="/admin/logout/" target="_blank"><span>注销</span></a></li>
{# <li><a href="#" target="_blank"><span>联系我们</span></a></li>#}
<li><a href="#" target="_blank"><span>{{ request.session.info.name }}</span></a></li>
</ul>
</nav>
<a class="btn btn-success" href="/uesr/model/form/add/">新建员工</a>
<table border="1" width="900px"> <!--border:表格边框,width:表格宽度-->
<caption>用户信息中心</caption> <!--标题标签,居中显示,仅有一个标题-->
<tr>
<th>id</th>
<th>姓名</th> <!--th标签:表格头,内容居中,加粗显示-->
<th>密码</th>
<th>年龄</th>
<th>余额</th>
<th>入职时间</th>
<th>性别</th>
<th>部门</th>
<th>操作</th>
</tr>
{% for obj in objects %}
<tr>
<td> {{ obj.id }}</td>
<td>{{ obj.name }}</td> <!--td标签:普通表格,内容左对齐-->
<td>{{ obj.password }}</td>
<td>{{ obj.age }}</td>
<td>{{ obj.account }}</td>
<td>{{ obj.create_time|date:"Y-m-d" }}</td>
<td>{{ obj.get_gender_display }}</td>
<td>{{ obj.depart.title }}</td>
<td>
<a class="btn-primary btn-xs" href="/user/{{ obj.id }}/edit/">编辑</a>
<a class="btn-danger btn-ns" href="/user/{{ obj.id }}/data/">删除</a>
</td>
</tr>
{% endfor %}
</table>
</body>
</html>
-
员工添加html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="container">
<div class="panel panel-default">
<div>
<h1> 编辑用户</h1>
</div>
<form method="post" novalidate>
<fieldset>
{% csrf_token %}
{% for iteam in form %}
<div class="form-group">
{{ iteam.label }}: {{ iteam }}<br><br>
<span style="color: red"> {{ iteam.errors.0 }}</span>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">
提交
</button>
</fieldset>
</form>
</div>
</div>
</body>
</html>
-
员工注册html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="container">
<div class="panel panel-default">
<div>
<h1> 用户管理系统注册表</h1>
</div>
<form method="post" novalidate>
<fieldset>
{% csrf_token %}
{% for iteam in form %}
<div class="form-group">
{{ iteam.label }}: {{ iteam }}<br><br>
<span style="color: red"> {{ iteam.errors.0 }}</span>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">
提交
</button>
</fieldset>
</form>
</div>
</div>
</body>
</html>
以上就是该程序的所有代码,只有登陆页面加了css
总结:
以上就是本期的分享,在后续的文章中给大家说明原理,并且代码内附注释,我们下期见