部门端 一.前言 本问主要是基于上一篇文章的最后一个案例的美化和升级
二.新建项目 记得安装库(Django,flask,requests),剩下就不多说了
三.表结构创建 先在excel表中设计一下
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 modelsclass 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 = models.ForeignKey(to="Department" , to_field="id" , 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>
五.部门列表展示
views.py
1 2 3 4 5 from django.shortcuts import renderdef department_list (request ): return render(request,'department_list.html' )
urls.py
1 2 3 4 5 6 from django.contrib import adminfrom django.urls import pathfrom app1 import viewsurlpatterns = [ 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 >
效果:
六.数据库数据 数据库操作
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 modelsdef 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 >
效果
七.添加页面 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),
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 %}
十一.department完整代码 urls.py
1 2 3 4 5 6 7 8 9 10 from django.urls import pathfrom app1 import viewsurlpatterns = [ 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 HttpResponsefrom django.shortcuts import render,redirectfrom app1 import modelsdef 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 );
然后做出来的效果就是这样
但是这里要补充几点
看这三行
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}} {{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 用户数据提交没有检验为空,也应有错误提示,每一个字段都需要重写,还要手动去获取
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 %}
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 >
可以发现修改后代码简短很多,看的很舒适,但是生成的效果会缺了下图中框出的部分
但是发现这个标签是属于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页面都有检验,我们要先关掉
改为中文