用户管理
mysql> desc employee_management_userinfo;
+-------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| name | varchar(16) | NO | | NULL | |
| password | varchar(64) | NO | | NULL | |
| age | int(11) | NO | | NULL | |
| account | decimal(10,2) | NO | | NULL | |
| create_time | datetime(6) | NO | | NULL | |
| gender | smallint(6) | NO | | NULL | |
| depart_id | bigint(20) | NO | MUL | NULL | |
+-------------+---------------+------+-----+---------+----------------+
向用户数据表中插入几行数据方便后面进行测试
insert into employee_management_userinfo(name,password,age,account,create_time,gender,depart_id) values("李云龙","123456",45,50000,"2020-03-24",1,2);
insert into employee_management_userinfo(name,password,age,account,create_time,gender,depart_id) values("张三丰","123456",45,60000,"2021-03-24",1,3);
insert into employee_management_userinfo(name,password,age,account,create_time,gender,depart_id) values("周杰伦","123456",45,70000,"2022-03-24",1,4);
用户列表
修改myproject/myproject/urls.py
from django.contrib import admin
from django.urls import path
from employee_management import views
urlpatterns = [
path('admin/', admin.site.urls),
path('depart/list/', views.depart_list),
path('depart/add/', views.depart_add),
path('depart/delete/', views.depart_delete),
path('depart//edit/', views.depart_edit),
path('user/list/', views.user_list),
]
修改myproject/employee_management/views.py
def user_list(request):
# 获取所有用户列表
user_data = UserInfo.objects.all()
# 用 python 的语法获取数据
"""
for obj in user_data:
# obj.get_gender_display() 表示匹配 男/女,原始字段名为gender,obj.get_字段名称_display()
# obj.create_time.strftime("%Y-%m-%d") 表示将时间格式转换成固定格式的字符串
# obj.depart.title 表示获取depart_id对应的部门名称,因为我们在models中定义表时与另外一张表设置了级联关系,有外键
print(obj.id, obj.name, obj.password, obj.age, obj.account, obj.get_gender_display(), obj.depart.title, obj.create_time.strftime("%Y-%m-%d"))
"""
return render(request, "user_list.html", {"user_data": user_data})
新建myproject/employee_management/templates/user_list.html
注意: HTML 中获取数据的方式与 Python 中有些不同
例如:
1.HTML中引入函数不能带括号, obj.get_gender_display()
2.日期类型转字符串有Django自己的格式, obj.create_time|date:“Y-m-d”
{% extends 'layout.html' %}
{% block content %}
div class="container">
div style="margin-bottom: 10px">
a class="btn btn-primary" href="/depart/add/" target="_blank">新建用户a>
div>
div>
div class="panel panel-default">
div class="panel-heading">
span class="glyphicon glyphicon-th-list" aria-hidden="true" style="margin-right: 5px;">span>
span>用户列表span>
div>
table class="table table-bordered">
thead>
tr>
th>IDth>
th>姓名th>
th>密码th>
th>年龄th>
th>性别th>
th>账户余额th>
th>入职时间th>
th>部门th>
th>操作th>
tr>
thead>
tbody>
{% for obj in user_data %}
tr>
th>{{ obj.id }}th>
td>{{ obj.name }}td>
td>{{ obj.password }}td>
td>{{ obj.age }}td>
td>{{ obj.get_gender_display }}td>
td>{{ obj.account }}td>
td>{{ obj.create_time|date:"Y-m-d" }}td>
td>{{ obj.depart.title }}td>
td>
a class="btn btn-primary btn-xs" href="/user/{{ obj.id }}/edit/">编辑a>
a class="btn btn-danger btn-xs" href="/user/delete/?nid={{ obj.id }}">删除a>
td>
tr>
{% endfor %}
tbody>
table>
div>
div>
div>
{% endblock %}
浏览器进行访问测试
用户添加
这里不演示最无脑原始的方式,漏洞百出,因为:
- 数据校验较麻烦
- 页面没有错误提示
- 页面上每一个字段都需要重新写一遍
- 关联的数据,需要手动获取并循环展示在页面
Django组件:
- Form组件(简便)
- ModelForm组件(最简便)
初识Form
- views.py
class MyForm(Form):
user = forms.CharField(widget=forms.Input)
pwd = forms.CharField(widget=forms.Input)
email = forms.CharField(widget=forms.Input)
def user_add(request):
if request.method == "GET":
form = MyForm()
return render(request, "user_add.html", {"form": form})
- user_add.html
{{ form.xxx }} 可以自动生成前端代码
form method="post">
{{ form.user }}
{{ form.pwd }}
{{ form.email }}
form>
也可以不指定,自动生成全部
form method="post">
{% for field in form %}
{{ field }}
{% endfor %}
form>
ModelForm
- models.py
from django.db import models
# Create your models here.
class Department(models.Model):
"""部门表"""
title = models.CharField(max_length=32, verbose_name='标题')
class UserInfo(models.Model):
"""员工表"""
name = models.CharField(max_length=16, verbose_name="姓名")
password = models.CharField(max_length=64, verbose_name="密码")
age = models.IntegerField(verbose_name="年龄")
account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
create_time = models.DateTimeField(verbose_name="入职时间")
depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE, verbose_name="部门")
gender_choices = (
(1, "男"),
(2, "女"),
)
gender = models.SmallIntegerField(choices=gender_choices,verbose_name="性别")
- views.py
class MyForm(ModelForm):
class Meta:
field = ["name", "password", "age"]
def user_add(request):
if request.method == "GET":
form = MyForm()
return render(request, "user_add.html", {"form": form})
- user_add.html
{{ form.xxx }} 可以自动生成前端代码
form method="post">
{{ form.user }}
{{ form.pwd }}
{{ form.email }}
form>
也可以不指定,自动生成全部
form method="post">
{% for field in form %}
{{ field }}
{% endfor %}
form>
用户添加(ModelForm)
修改myproject/employee_management/views.py
########################## ModelForm 演示 #############################
from django import forms
class UserModelForm(forms.ModelForm):
### 自定义数据校验
# 例如: 用户名最小三个字符
#name = forms.CharField(min_length=3, label="用户名")
class Meta:
model = UserInfo
fields = ["name", "password", "age", "account", "create_time", "gender", "depart"]
# 逐一控制标签的样式
# widgets = {
# "name": forms.TextInput(attrs={"class": "form-control"}),
# "password": forms.PasswordInput(attrs={"class": "form-control"}),
# }
# 这里让日期可以手动点击鼠标选择,所以单独拎出来,加上日期插件
widgets = {
"create_time": forms.DateTimeInput(attrs={'class': 'form-control', 'id': 'myDate'}),
}
# 循环找到所有的插件,添加 "class": "form-control"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for name, field in self.fields.items():
# 可以排除指定的字段
if name == "create_time":
continue
print(name, field)
field.widget.attrs = {"class": "form-control"}
def user_model_form_add(request):
"""添加用户(ModelForm版本)"""
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():
print(form.cleaned_data)
# 直接保存至数据库
form.save()
return redirect("/user/list/")
# 校验失败(在页面上显示错误信息)
return render(request, "user_model_form_add.html", {"form": form})
修改myproject/myproject/urls.py
from django.contrib import admin
from django.urls import path
from employee_management import views
urlpatterns = [
path('admin/', admin.site.urls),
path('depart/list/', views.depart_list),
path('depart/add/', views.depart_add),
path('depart/delete/', views.depart_delete),
path('depart//edit/', views.depart_edit),
path('user/list/', views.user_list),
path('user/model/form/add/', views.user_model_form_add),
]
新建myproject/employee_management/templates/user_model_form_add.html
{% extends 'layout.html' %}
{% block content %}
div class="container">
div class="panel panel-default">
div class="panel-heading">
h3 class="panel-title">添加用户/h3>
/div>
div class="panel-body">
form action="/user/model/form/add/" 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 %}
/body>
/html>
修改myproject/employee_management/models.py
目的是让自动生成的部门字段不显示”对象”本身,显示对象对应的”title”
class Department(models.Model):
"""部门表"""
title = models.CharField(max_length=32, verbose_name='标题')
def __str__(self):
return self.title
修改后再次刷新
日期设置
目前日期只能手动输入,如果想要鼠标点击选择,需要调用datetimepicker
插件
插件下载地址:
链接:https://pan.baidu.com/s/1yN-L7bhwdSXwfYfh2MUj2A
提取码:yyds
下载完成后,我将插件放在了
/root/python/myproject/static/
下
修改myproject/employee_management/templates/layout.html
引入datetimepicker
插件
调用方法: 在对应的标签中加入”id=myDate”
!DOCTYPE html>
html lang="en">
head>
meta charset="UTF-8">
title>Document/title>
link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1/css/bootstrap.css">
link rel="stylesheet" href="/static/plugins/font-awesome-4.7.0/css/font-awesome.css">
!--JQUERY-->
script type="text/javascript" src="/static/jquery/jquery-1.11.1-min.js">/script>
!--BOOTSTRAP框架-->
link rel="stylesheet" type="text/css" href="/static/jquery/bootstrap_3.3.0/css/bootstrap.min.css">
script type="text/javascript" src="/static/jquery/bootstrap_3.3.0/js/bootstrap.min.js">/script>
!--BOOTSTRAP_DATETIMEPICKER插件-->
link rel="stylesheet" type="text/css" href="/static/jquery/bootstrap-datetimepicker-master/css/bootstrap-datetimepicker.min.css">
/head>
body>
!-- 此处省略一部分代码 -->
script type="text/javascript">
$(function () {
//当容器加载完成,对容器调用工具函数
$("#myDate").datetimepicker({
language: 'zh-CN', //语言
format: 'yyyy-mm-dd',//日期的格式
minView: 'month', //可以选择的最小视图
initialDate: new Date(),//初始化显示的日期
autoclose: true,//设置选择完日期或者时间之后,日否自动关闭日历
todayBtn: true,//设置自动显示为今天
clearBtn: false//设置是否清空按钮,默认为false
});
});
/script>
/body>
/html>
如何使用呢
其实在上面的代码中我已经提前写上了
下图是Django中ModelForm修改标签属性的方式,在widgets
字典中定义
attrs={'class': 'form-control', 'id': 'myDate'}
最终效果
数据校验错误提示
修改myproject/myproject/settings.py
改为中文,目的是为了让页面提示错误信息时显示中文,否则会显示英文
#LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans'
如果我们没有写入任何内容直接点击”保存”,那么页面会提示错误
因为我们在/root/python/myproject/employee_management/templates/user_model_form_add.html
中加入了{{ field.errors.0 }}
字段
编辑用户
修改myproject/employee_management/views.py
def user_edit(request, nid):
"""编辑用户"""
row_obj = UserInfo.objects.filter(id=nid).first()
# GET请求
if request.method == "GET":
form = UserModelForm(instance=row_obj)
return render(request, "user_edit.html", {"form": form})
# POST请求
form = UserModelForm(data=request.POST, instance=row_obj)
if form.is_valid():
form.save()
return redirect("/user/list/")
return render(request, "user_edit.html", {"form": form})
修改/root/python/myproject/myproject/urls.py
path('user//edit/', views.user_edit),
增加/root/python/myproject/employee_management/templates/user_edit.html
{% extends 'layout.html' %}
{% block content %}
div class="container">
div class="panel panel-default">
div class="panel-heading">
h3 class="panel-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 %}
body>
html>
浏览器访问测试,点击”编辑”
但是发现上面的时间有些问题,应该只显示年月日就可以了,不应该显示时分秒
需要修改数据库models
更新数据库表结构
python3 manage.py makemigrations
python3 manage.py migrate
此时还需要更改一个地方
浏览器刷新
删除用户
修改myproject/employee_management/views.py
def user_delete(request, nid):
"""用户删除"""
UserInfo.objects.filter(id=nid).delete()
return redirect("/user/list/")
修改myproject/myproject/urls.py
path('user//delete/', views.user_delete),
修改myproject/employee_management/templates/user_list.html
td>
a class="btn btn-primary btn-xs" href="/user/{{ obj.id }}/edit/">编辑a>
a class="btn btn-danger btn-xs" href="/user/{{ obj.id }}/delete/">删除a>
td>
浏览器测试