部门端

一.前言

本问主要是基于上一篇文章的最后一个案例的美化和升级

二.新建项目

记得安装库(Django,flask,requests),剩下就不多说了

1772028347884

三.表结构创建

先在excel表中设计一下

1772029248712

models.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
from django.db import models

# Create your models here.
class Department(models.Model):
title = models.CharField(verbose_name="部门",max_length=100)

class UserInfo(models.Model):
name=models.CharField(max_length=100)
password=models.CharField(max_length=100)
age=models.IntegerField()
account=models.DecimalField(max_digits=10,decimal_places=2,default=0)
create_date=models.DateTimeField(auto_now_add=True)

# 无约束
# depart_id = models.BigIntegerField(verbose_name="部门ID")

# 1.有约束
# - to, 与那张表关联
# - to_field, 表中的那一列关联
# 2.django自动
# - 写的depart
# - 生成数据列 depart_id
# 3.部门表被删除
# ### 3.1 级联删除
depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)

# ### 3.2 置空
# depart = models.ForeignKey(to="Department", to_field="id", null=True, blank=True, on_delete=models.CASCADE)

gender_choices = (
(1, "男"),
(2, "女"),
)

gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)

四.生成数据库

首先就是Django连接上数据库,这里记得要下载mysqlclient

1
2
python manege.py makemigration
python manage.py migrate
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
mysql> show tables;
+----------------------------+
| Tables_in_list |
+----------------------------+
| app1_department |
| app1_userinfo |
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
12 rows in set (0.00 sec)

mysql> desc app1_department;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | bigint | NO | PRI | NULL | auto_increment |
| title | varchar(100) | NO | | NULL | |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> desc app1_userinfo;
+-------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+----------------+
| id | bigint | NO | PRI | NULL | auto_increment |
| name | varchar(100) | NO | | NULL | |
| password | varchar(100) | NO | | NULL | |
| age | int | NO | | NULL | |
| account | decimal(10,2) | NO | | NULL | |
| create_date | datetime(6) | NO | | NULL | |
| gender | smallint | NO | | NULL | |
| depart_id | bigint | NO | MUL | NULL | |
+-------------+---------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)

mysql>

五.部门列表展示

1772086915060

views.py

1
2
3
4
5
from django.shortcuts import render

# Create your views here.
def department_list(request):
return render(request,'department_list.html')

urls.py

1
2
3
4
5
6
from django.contrib import admin
from django.urls import path
from app1 import views
urlpatterns = [
path('depart/list/', views.department_list),
]

department_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
61
62
63
64
65
66
67
68
69
70
71
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plungs/bootstrap/bootstrap.css' %}">
</head>
<body>
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container">
<a class="navbar-brand" href="#">公司用户管理系统</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="/depart/list">部门管理</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>

</ul>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false" style="margin-right:50px;">
lion
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">我的信息</a></li>
<li><a class="dropdown-item" href="#">个人资料</a></li>
<li><a class="dropdown-item" href="#">注销</a></li>
</ul>
</li>
<a href="#" style="text-decoration:none;color:black;">
登录
</a>
</div>
</div>
</nav>

<div class="container" style="margin-top:30px;">
<button type="button" class="btn btn-primary">新建部门</button>
<div class="bd-example">
<table class="table table-bordered" style="margin-top:10px;">
<thead>
<tr>
<th scope="col" style="font-size:20px;">ID</th>
<th scope="col" style="font-size:20px;">名称</th>
<th scope="col" style="font-size:20px;">操作</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row" style="font-size:25px;">1</th>
<td style="font-size:25px;">销售部</td>
<td>
<button type="button" class="btn btn-success">添加</button>
<button type="button" class="btn btn-danger">删除</button>
</td>
</tr>
</tbody>

</table>
</div>
</div>
<script src="{% static 'plungs/js/bootstrap.bundle.min.js' %}"></script>
<script src="{% static 'js/jquery-4.0.0.js' %}"></script>
</body>
</html>

效果:

1772090793247

六.数据库数据

数据库操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> insert into app1_department(title) values("IT部门"),("销售部");
Query OK, 2 rows affected (0.02 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> select * from app1_department;
+----+--------+
| id | title |
+----+--------+
| 1 | IT部门 |
| 2 | 销售部 |
+----+--------+
2 rows in set (0.00 sec)

mysql>

views.py

1
2
3
4
5
from app1 import models
def department_list(request):
date_department = models.Department.objects.all()

return render(request,'department_list.html',{'date_department':date_department})

.html

1
2
3
4
5
6
7
8
9
10
11
12
13
<tbody>
{% for it in date_department %}
<tr>
<th scope="row" style="font-size:23px;">{{it.id}}</th>
<td style="font-size:23px;">{{it.title}}</td>
<td>
<button type="button" class="btn btn-success">添加</button>
<button type="button" class="btn btn-danger">删除</button>
</td>
</tr>
{% endfor %}
</tbody>

1772092938763

效果

1772092969626

七.添加页面

views.py

1
2
3
4
5
6
7
8
9
def department_add(request):
if request.method == 'GET':
return render(request,'department_add.html')
else:
name=request.POST.get('title')
print(name)
models.Department.objects.create(title=name)
return render(request,'department_add.html')

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
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plungs/bootstrap/bootstrap.css' %}">
</head>
<body>
<div class="container" style="margin-top:30px;">
<h3>新建部门</h3>
<form class="row row-cols-lg-auto g-3 align-items-center" method="post" action="/depart/add/">
{% csrf_token %}
<div class="col-12">
<label class="visually-hidden" for="inlineFormInputGroupUsername">Username</label>
<div class="input-group">
<div class="input-group-text">部门</div>
<input type="text" class="form-control" id="inlineFormInputGroupUsername" placeholder="depart_name" name="title">
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
<div class="col-12">
<a href="/depart/list/">
<button type="button" class="btn btn-primary">返回</button>
</a>
</div>
</form>
</div>

<script src="{% static 'plungs/js/bootstrap.bundle.min.js' %}"></script>
<script src="{% static 'js/jquery-4.0.0.js' %}"></script>
</body>
</html>

八.删除页面

views.py

1
2
3
4
5
def department_delete(request):
nid=request.GET.get('nid')
models.Department.objects.filter(id=nid).delete()
return render(request,'department_delete.html')

html

1
2
3
4
5
6
7
8
<body>
<h3>
<a href="/depart/list/" style="text-decoration:none;color:black;">
删除成功
</a>
</h3>
</body>

还要注意_list的html的按钮跳转格式

1
2
3
4
<a href="/depart/delete/?nid={{it.id}}">
<button type="button" class="btn btn-danger">删除</button>
</a>

九.编辑页面

其实和八的部分大差不差,也是传给他id然后update一下就好了

这里介绍另外一种写法

urls.py

1
2
path('depart/<int:nid>/edit/', views.department_edit),	#这样接收到地址是http://127.0.0.1:8000/depart/8/edit/

views.py

1
2
3
4
5
6
7
8
9
def department_edit(request,nid):
date=models.Department.objects.filter(id=nid).first()
print(date.title)
if request.method == 'GET':
return render(request,'department_edit.html',{date:date})
else:
models.Department.objects.filter(id=nid).update(title=request.POST.get('title'))
return redirect("/depart/list")

十.模板的继承

定义模板

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<h1>用户列表</h1>
<body>
{% block content %}{% endblock %}
</body>
</html>
<a href="/info/subscribe" style="text-decoration:none">添加</a>

使用模板

1
2
3
4
5
{% extends  'layout.html' %}
{% block content %}
<h1>哈哈哈哈</h1>
{% endblock %}

1772098539048

十一.department完整代码

urls.py

1
2
3
4
5
6
7
8
9
10
from django.urls import path
from app1 import views
urlpatterns = [
path('depart/list/', views.department_list),
path('depart/add/', views.department_add),
path('depart/delete/', views.department_delete),
path('depart/<int:nid>/edit/', views.department_edit),
]


views.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
from django.http import HttpResponse
from django.shortcuts import render,redirect

# Create your views here.
from app1 import models
def department_list(request):
date_department = models.Department.objects.all()

return render(request,'department_list.html',{'date_department':date_department})
def department_add(request):
if request.method == 'GET':
return render(request,'department_add.html')
else:
name=request.POST.get('title')
print(name)
models.Department.objects.create(title=name)
return render(request,'department_add.html')

def department_delete(request):
nid=request.GET.get('nid')
models.Department.objects.filter(id=nid).delete()
return redirect("/depart/list")

def department_edit(request,nid):
date=models.Department.objects.filter(id=nid).first()
print(date.title)
if request.method == 'GET':
return render(request,'department_edit.html',{"date":date})
else:
models.Department.objects.filter(id=nid).update(title=request.POST.get('title'))
return redirect("/depart/list")

department_add.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
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plungs/bootstrap/bootstrap.css' %}">
</head>
<body>
<div class="container" style="margin-top:30px;">
<h3>新建部门</h3>
<form class="row row-cols-lg-auto g-3 align-items-center" method="post" action="/depart/add/">
{% csrf_token %}
<div class="col-12">
<label class="visually-hidden" for="inlineFormInputGroupUsername">Username</label>
<div class="input-group">
<div class="input-group-text">部门</div>
<input type="text" class="form-control" id="inlineFormInputGroupUsername" placeholder="depart_name" name="title">
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
<div class="col-12">
<a href="/depart/list/">
<button type="button" class="btn btn-primary">返回</button>
</a>
</div>
</form>
</div>

<script src="{% static 'plungs/js/bootstrap.bundle.min.js' %}"></script>
<script src="{% static 'js/jquery-4.0.0.js' %}"></script>
</body>
</html>

department_edit.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
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plungs/bootstrap/bootstrap.css' %}">
</head>
<body>
<div class="container" style="margin-top:30px;">
<h3>编辑部门名称</h3>
<form class="row row-cols-lg-auto g-3 align-items-center" method="post"">
{% csrf_token %}
<div class="col-12">
<label class="visually-hidden" for="inlineFormInputGroupUsername">Username</label>
<div class="input-group">
<div class="input-group-text">部门</div>
<input type="text" class="form-control" id="inlineFormInputGroupUsername" placeholder="{{date.title}}" name="title">
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">Submit</button>
</div>

<script src="{% static 'plungs/js/bootstrap.bundle.min.js' %}"></script>
<script src="{% static 'js/jquery-4.0.0.js' %}"></script>
</body>
</html>

department_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
61
62
63
64
65
66
67
68
69
70
71
72
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plungs/bootstrap/bootstrap.css' %}">
</head>
<body>
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container">
<a class="navbar-brand" href="#">公司用户管理系统</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="/depart/list">部门管理</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>

</ul>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false" style="margin-right:50px;">
lion
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">我的信息</a></li>
<li><a class="dropdown-item" href="#">个人资料</a></li>
<li><a class="dropdown-item" href="#">注销</a></li>
</ul>
</li>
<a href="#" style="text-decoration:none;color:black;">
登录
</a>
</div>
</div>
</nav>

<div class="container" style="margin-top:30px;">
<a href="/depart/add/">
<button type="button" class="btn btn-primary">新建部门</button>
</a>
<div class="bd-example">
<table class="table table-bordered" style="margin-top:10px;">
<thead>
<tr>
<th scope="col" style="font-size:20px;">ID</th>
<th scope="col" style="font-size:20px;">名称</th>
<th scope="col" style="font-size:20px;">操作</th>
</tr>
</thead>
<tbody>
{% for it in date_department %}
<tr>
<th scope="row" style="font-size:23px;">{{it.id}}</th>
<td style="font-size:23px;">{{it.title}}</td>
<td>
<a href="/depart/{{it.id}}/edit">
<button type="button" class="btn btn-success">编辑</button>
</a>
<a href="/depart/delete/?nid={{it.id}}">
<button type="button" class="btn btn-danger">删除</button>
</a>
</td>
</tr>
{% endfor %}
</tbody>

用户端

一.用户HTML页面

思路和前面一样就不细说代码了

先喂一波数据

1
2
3
4
5
6
7
INSERT INTO app1_userinfo (name, password, age, account, create_date, gender, depart_id) VALUES
('张三', '123456', 25, 8000.00, '2021-11-23', 1, 12),
('李四', '123456', 28, 9500.00, '2019-02-03', 1, 12),
('王芳', '123456', 26, 8800.00, '2022-02-22', 0, 13),
('赵丽', '123456', 24, 7800.00, '2020-04-03', 0, 13),
('刘伟', '123456', 32, 12000.00, '2010-03-04', 1, 14);

然后做出来的效果就是这样

1772109841714

但是这里要补充几点

看这三行

1772109895883
1
2
我们正常{{it.create_date}}是像这样”Nov. 23, 2021, midnight“,加上| date:"Y-m-d"就会像这样“	2021-11-23”,如果y是小写那么只有两位整数

1
2
3
4
5
6
7
8
9
gender_choices = (
(1, "男"),
(0, "女"),
)
gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)

{{it.gender}} #数据显示1/2
{{it.get_gender_display}} #会显示男/女

1
2
3
4
{{it.depart_id会显示/depart/list表中部门的id}}
{{it.depart}}会显示部门(包括id和部门)
{{it.depart.title}}只显示部门

二.新建员工数据

老方法/Form组件(小简便)/ModelForm组件(最简便)

老方法

数据构建就和前面的一样,但这里要注意的是

性别/部门方面

下面以性别为例

1
2
3
4
5
6
7
8
9
10
11
gender_choices = (
(1, "男"), #元组
(0, "女"), #元组
)
gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)

所以我可以先引入date=models.XX.gender_choice,然后导入html,然后用
<select>
<option value={{it.0}}>{{it.first}}</option>
</select>

缺点:

1
2
用户数据提交没有检验为空,也应有错误提示,每一个字段都需要重写,还要手动去获取

Form

views.py

1
2
3
4
5
6
7
class MyForm(forms.Form):
user=forms.CharField(widget=forms.TextInputInput)
password = forms.CharField(widget=forms.PasswordInput)
if request.method="GET":
form=MyForm()
return render("request","index.html",{"form":form})

index.html

1
2
3
4
{% for it in form %}
{{it}}
{% endfor %}

ModelForm

views.py

1
2
3
4
5
6
7
8
9
class userinfo(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = ('username','email','password')

def add(request):
userinfo=userinfo()
renturn ...{"userform":userinfo}

使用就是{{userinfo.username}}

案例

1
2
3
4
5
6
class userinfo(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = ('name','password','age','account','create_date','depart','gender')


1
2
3
4
5
6
7
8
9
10
11
12
<form class="row g-3">
{% for it in user %}
<div class="col-md-6">
<label class="form-label">{{it.label}}</label>
{{it}}
</div>
{% endfor %}
<div class="col-12">
<button type="submit" class="btn btn-primary">注册</button>
</div>
</form>

可以发现修改后代码简短很多,看的很舒适,但是生成的效果会缺了下图中框出的部分

1772116267710

但是发现这个标签是属于forms的内部,那要怎么运用呢

1
2
3
4
5
6
7
8
9
class userinfo(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = ('name','password','age','account','create_date','depart','gender')
widgets = {
'name':forms.TextInput(attrs={'class':'form-control'}),
。。。。。。
}

但是这样子也要改好多

1
2
3
4
5
6
7
8
9
class userinfo(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = ('name','password','age','account','create_date','depart','gender')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for name, field in self.fields.items():
field.widget.attrs.update({'class': 'form-control'})

views.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
class userinfo(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = ('name','password','age','account','create_date','depart','gender')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for name, field in self.fields.items():
field.widget.attrs.update({'class': 'form-control'})
def user_add(request):
if request.method == 'GET':
user=userinfo()
return render(request,'user_add.html',{"user":user})

else:
name=request.POST.get('name')
password=request.POST.get('password')
age=request.POST.get('age')
account=request.POST.get('account')
create_date=request.POST.get('create_date')
depart=request.POST.get('depart')
gender=request.POST.get('gender')
models.UserInfo.objects.create(name=name,password=password,age=age,account=account,create_date=create_date,depart_id=depart,gender=gender)
return redirect("/user/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
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plungs/bootstrap/bootstrap.css' %}">
</head>
<body>
<div class="container" style="margin-top:60px;">
<div class="bd-example m-0 border-0">
<form class="row g-3" method="post">
{% csrf_token %}
{% for it in user %}
<div class="col-md-6">
<label class="form-label">{{it.label}}</label>
{{it}} #这个就是高明之处了,会自动匹配对应格式
</div>
{% endfor %}
<div class="col-12">
<button type="submit" class="btn btn-primary">注册</button>
</div>
</form>
</div>
</div>

<script src="{% static 'plungs/js/bootstrap.bundle.min.js' %}"></script>
<script src="{% static 'js/jquery-4.0.0.js' %}"></script>
</body>
</html>

还可以将新建函数这样子改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 原:  else:
name=request.POST.get('name')
password=request.POST.get('password')
age=request.POST.get('age')
account=request.POST.get('account')
create_date=request.POST.get('create_date')
depart=request.POST.get('depart')
gender=request.POST.get('gender')
models.UserInfo.objects.create(name=name,password=password,age=age,account=account,create_date=create_date,depart_id=depart,gender=gender)
return redirect("/user/list")



改: else:
shuju=userinfo(request.POST)
if shuju.is_valid():
shuju.save()
return redirect("/user/list")

那如果输入为空要显示报错要怎么办呢,正常的html页面都有检验,我们要先关掉

1772195302874

1772195319630

改为中文

1772195413543