Django 03 :员工管理【 模板继承 + Form + ModelForm】

2023-10-22 09:20

本文主要是介绍Django 03 :员工管理【 模板继承 + Form + ModelForm】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 1、模板的继承
    • 2、用户管理
      • 导航栏的跳转效果
      • 用户管理表格设计
      • 向表格添加用户数据
    • 3、新建用户(原始方法)
      • 基础效果
      • 优化
      • 完成提交(数据库)
    • 4、Django组件:Form 和 ModelForm
      • 4.1、初识Form
        • 1、views.py
        • 2、user_add.html
      • 4.2、ModelForm(推荐)
        • 0、models.py
        • 1、views.py
        • 2、user_add.html
    • 5、新建用户(ModelForm)
      • 错误提示

上一篇: Django 02 :部门管理 【面板设计(Bootstrap)+部门的增删改查(Django+MySQL)】_.末明.的博客-CSDN博客

1、模板的继承

上一篇文章中我们发现,我们每创建一个新页面(HTML文件),都要重复的去做引入静态文件、导航条等操作,下面提供一个更简单的方式:模板继承

  • 部门列表
  • 添加部门
  • 编辑部门

定义母版:layout.html

母版包含内容:

  • 静态文件的引入
  • 导航条
  • 子版部分

如下,我们规定好母版的内容,此时子板只需要填写{% block content %}{% endblock %}的内容就ok了

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}"><style>.navbar {border-radius: 0;}</style>
</head>
<body>{# 子板部分 #}
<div>{% block content %}{% endblock %}
</div><script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
</body>
</html>

子模板:

{% extends 'layout.html' %}{% block content %}{# 子板的内容 #}
{% endblock %}

当然,我们还可以在模板中多添加点block,如下,我们新增了css、js

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="{% static 'plugin...min.css' %}">{% block css %}{% endblock %}
</head>
<body><div>{% block content %}{% endblock %}</div><script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>{% block js %}{% endblock %}
</body>
</html>

继承母版:

{% extends 'layout.html' %}{% block css %}<link rel="stylesheet" href="{% static 'pluxxx.css' %}"><style>...</style>
{% endblock %}{% block content %}<h1>首页</h1>
{% endblock %}{% block js %}<script src="{% static 'js/jqxxxin.js' %}"></script>
{% endblock %}

这样我们就可以重构一下之前的前端代码:

请添加图片描述

2、用户管理

urls.py

path('user/list/', views.user_list),

views.py

def user_list(request):"""用户管理"""return render(request, 'user_list.html')

user_list.html

直接copydepart_list.html,修改一下文字部分即可

{% extends 'layout.html' %}{% block content %}{# 用户列表 #}<div class="container"><div style="margin-bottom: 10px"><a class="btn btn-success" href="/depart/add/" >{# 可以添加一个 target="_blank" : 使页面在新页面打开,如果不设置,会在原页面打开(这里我们还是在当前页面打开) #}<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>新建用户</a>{#新建一个 depart_add.html , 用来写新建部门界面#}</div><div class="panel panel-default"><!-- Default panel contents --><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></tr></thead><tbody><tr><th>123</th><td>321</td><td><a class="btn btn-primary btn-xs" href="#">编辑</a><a class="btn btn-danger btn-xs" href="#">删除</a></td></tr>{#                {% for obj in queryset %}#}
{#                    <tr>#}
{#                        <th>{{ obj.id }}</th>#}
{#                        <td>{{ obj.title }}</td>#}
{#                        <td>#}
{#                            <a class="btn btn-primary btn-xs" href="/depart/{{ obj.id }}/edit/">编辑</a>#}{# btn ==> 添加btn的按钮#}{# btn-primary ==> 蓝色按钮(按钮的样式)#}{# btn-xs ==> 	这会让按钮看起来特别小(按钮大小)#}
{#                            <a class="btn btn-danger btn-xs" href="/depart/detele/?nid={{ obj.id }}">删除</a>#}
{#                        </td>#}
{#                    </tr>#}
{#                {% endfor %}#}</tbody></table></div></div>
{% endblock %}

效果展示:

在这里插入图片描述

导航栏的跳转效果

任务:点击导航栏的“用户管理”,即可跳转到用户管理界面

修改导航栏

layout.html

<ul class="nav navbar-nav"><li><a href="/depart/list/">部门管理</a></li><li><a href="/user/list/">用户管理</a></li><li><a href="#">Link</a></li></ul>

这样就完成了跳转功能

用户管理表格设计

user_list.html

<!-- 表格部分 --><table class="table table-bordered"><thead><tr><th>ID</th><th>姓名</th><th>密码</th><th>年龄</th><th>余额</th><th>入职时间</th><th>性别</th><th>所属部门</th><th>操作</th></tr></thead><tbody><tr><th>123</th><td>321</td><td>321</td><td>321</td><td>321</td><td>321</td><td>321</td><td>321</td><td><a class="btn btn-primary btn-xs" href="#">编辑</a><a class="btn btn-danger btn-xs" href="#">删除</a></td></tr>

效果展示:

在这里插入图片描述

向表格添加用户数据

回顾一下我们之前设计的用户管理表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1nzjvPUn-1645714937055)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20220223200244874.png)]

写点sql语句,添加用户:

insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id) values("韩超","666",23,100.68,"2020-01-11",2,1);insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id) values("刘东","123",23,100.68,"2010-11-11",1,1);insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id) values("朱虎飞","999",33,9900.68,"2021-05-11",1,1);

问题:

mysql> insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id) values("刘东","123",23,100.68,"2010-11-11",1,4);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`employee`.`app01_userinfo`, CONSTRAINT `app01_userinfo_depart_id_e22e0907_fk_app01_department_id` FOREIGN KEY (`depart_id`) REFERENCES `app01_department` (`id`))

输入第二个数据报错:我们收到错误"无法添加或更新子行:外键"
约束失败"。

原因:在插入含有外键的表中,若要插入外键为空时,直接insert则会报错,注意他最后一个参数是【4】,我们定义的【1】是【男】、【2】是【女】,【4】在范围之外

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s0MZPj7o-1645714937056)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20220223205100423.png)]

我们修改一下views.py看一下效果:

def user_list(request):"""用户管理"""# 获取所有的用户列表queryset = models.UserInfo.objects.all()for obj in queryset:print(obj.id, obj.name, obj.accoun, obj.create_time.strftime("%Y-%m-%d"), type(obj.create_time))return render(request, 'user_list.html')

PS:关于入职时间
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2kV9HCmG-1645714937056)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20220223210307219.png)]

效果展示:

运行django项目,跳转到http://127.0.0.1:8000/user/list/

Django version 3.2.6, using settings 'employeemanage.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
6 韩超 100.68 2020-01-11 <class 'datetime.datetime'>
7 刘东 100.68 2010-11-11 <class 'datetime.datetime'>
8 朱虎飞 9900.68 2021-05-11 <class 'datetime.datetime'>

如何获取关联的数据呢?

def user_list(request):"""用户管理"""# 获取所有的用户列表queryset = models.UserInfo.objects.all()for obj in queryset:print(obj.id, obj.name, obj.account, obj.create_time.strftime("%Y-%m-%d"), type(obj.create_time))# 想要获取关联的数据# 方式一: 传统方法,根据id获取关联的数据temp = models.Department.objects.filter(id=obj.depart_id).first()print(temp.title)# 方式二: Django的方法(注意区别obj.depart_id与obj.depart.title)print(obj.depart_id)  # 获取数据库中存储的那个字段值print(obj.depart.title)  # 根据id自动去关联的表中获取哪一行数据depart对象return render(request, 'user_list.html')

效果展示:

6 韩超 100.68 2020-01-11 <class 'datetime.datetime'>
IT部门
1
IT部门
7 刘东 100.68 2010-11-11 <class 'datetime.datetime'>
IT部门
1
IT部门
8 朱虎飞 9900.68 2021-05-11 <class 'datetime.datetime'>
IT部门
1
IT部门

然后就是把数据库的数据传到前端了

user_list.html

<!-- 表格部分 --><table class="table table-bordered"><thead><tr><th>ID</th><th>姓名</th><th>密码</th><th>年龄</th><th>余额</th><th>入职时间</th><th>性别</th><th>所属部门</th><th>操作</th></tr></thead><tbody>{% for obj in queryset %}<tr><th>{{ obj.id }}</th><td>{{ obj.name }}</td><td>{{ obj.password }}</td><td>{{ obj.age }}</td><td>{{ obj.account }}</td>{# 模板语法是不能加括号的,需要加括号时,他会自动帮你加上 #}{# <td>{{ obj.create_time.strftime("%Y-%m-%d") }}</td>#}{# <td>{{ obj.get_gender_display() }}</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 btn-primary btn-xs" href="#">编辑</a><a class="btn btn-danger btn-xs" href="#">删除</a></td></tr>{% endfor %}</tbody></table>

注意区别Python语法与模板语法:

{# 模板语法是不能加括号的,需要加括号时,他会自动帮你加上 #}
{# <td>{{ obj.create_time.strftime("%Y-%m-%d") }}</td>#}
{# <td>{{ obj.get_gender_display() }}</td>#}
<td>{{ obj.create_time|date:"Y-m-d"}}</td>
<td>{{ obj.get_gender_display }}</td>
<td>{{ obj.depart.title }}</td>

可能遇到的问题:

Exception Type:	TemplateSyntaxError
Exception Value:	
Could not parse the remainder: ': "Y-m-d"' from 'obj.create_time|date: "Y-m-d"'

原因:

<td>{{ obj.create_time|date:"Y-m-d"}}</td>对于"Y-m-d",其前面一个空格都不能有,否则就会报上述错误,格式要求很严格

前端效果展示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hVgqapjH-1645714937056)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20220223224500635.png)]

3、新建用户(原始方法)

三种方式

  • 原始方法思路:麻烦

  • Django组件

    • Form组件(简便)
    • ModelForm组件(最简便)

我们首先体验一下用原始的方式实现新增用户,下一节中再使用Django组件

基础效果

  • (1)user_list.html

修改href

<a class="btn btn-success" href="/user/add/">{# 可以添加一个 target="_blank" : 使页面在新页面打开,如果不设置,会在原页面打开(这里我们还是在当前页面打开) #}<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>新建用户</a>
  • (2)urls.py
path('user/add/', views.user_add),
  • (3)user_add.html

    复用depart_add.html的代码,并新增几个输入框用来填写用户的各种信息(很繁琐,不断的去做重复的共工作建立输入框)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RmHTwrnM-1645714937057)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20220224135718717.png)]

特别是“性别”和“部门”俩属性,需要特殊处理,我们输入值只能是已有的选项

{% extends 'layout.html' %}{% block content %}{# 新建用户部分 #}<div><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">{% csrf_token%}<div class="form-group"><label>姓名</label><input type="text" class="form-control" placeholder="姓名" ></div><div class="form-group"><label>密码</label><input type="text" class="form-control" placeholder="密码"></div><div class="form-group"><label>年龄</label><input type="text" class="form-control" placeholder="年龄"></div><div class="form-group"><label>余额</label><input type="text" class="form-control" placeholder="余额"></div><div class="form-group"><label>入职时间</label><input type="text" class="form-control" placeholder="入职时间"></div><div class="form-group"><label>性别</label>{#<input type="text" class="form-control" placeholder="性别">#}<select class="form-control"><option value="1"></option><option value="2"></option></select></div><div class="form-group"><label>部门</label>{# <input type="text" class="form-control" placeholder="部门"> #}<select class="form-control"><option value="1">IT部门</option><option value="2">媒体企划</option></select></div><button type="submit" class="btn btn-primary">提交</button></form></div></div></div>
</div>{% endblock %}

效果展示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O1ICOY4w-1645714937057)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20220224140548416.png)]

优化

前面,对于“部门”我们是写死的,这样很不好,部门数量太多、部门关联的ID变化、新增部门等等情况都会引来麻烦

  • views.py
def user_add(request):"""添加用户"""# 拿到部门信息,传到前端context = {'gender_choice' : models.UserInfo.gender_choices,'depart_list' : models.Department.objects.all(),}return render(request, "user_add.html", context)
  • user_add.html
<div class="form-group"><label>部门</label>{# <input type="text" class="form-control" placeholder="部门"> #}<select class="form-control">{# <option value="1">IT部门</option>#}{# <option value="2">媒体企划</option>#}{# value 的值必须与数据库相对应 #}{% for item in depart_list %}<option value="{{ item.id }}">{{ item.title }}</option>{% endfor %}</select></div>

完成提交(数据库)

老样子

  • (1)对前端各个信息一个一个获取
  • (2)后端( views.py / user_add() )中接收前端提交的数据(POST)
  • (3)传入数据库
  • (4)返回用户列表界面
  • (1)对前端各个信息一个一个获取

在最后加【name】属性

<div class="form-group"><label>姓名</label><input type="text" class="form-control" placeholder="姓名" name="user"/></div><div class="form-group"><label>密码</label><input type="text" class="form-control" placeholder="密码" name="pwd"/></div><div class="form-group"><label>年龄</label><input type="text" class="form-control" placeholder="年龄" name="age"/></div><div class="form-group"><label>余额</label><input type="text" class="form-control" placeholder="余额" name="ac"/></div><div class="form-group"><label>入职时间</label><input type="text" class="form-control" placeholder="入职时间" name="ctime"/></div>
  • (2)后端( views.py / user_add() )中接收前端提交的数据(POST)

将用户的一堆属性一个一个获取

# 获取用户提交的数据
user = request.POST.get('user')
pwd = request.POST.get('pwd')
age = request.POST.get('age')
account = request.POST.get('ac')
ctime = request.POST.get('ctime')
gender = request.POST.get('gd')
depart_id = request.POST.get('dp')
  • (3)传入数据库
# 添加到数据库中
models.UserInfo.objects.create(name=user, password=pwd, age=age,account=account, create_time=ctime,gender=gender, depart_id=depart_id)
  • (4)返回用户列表界面
# return render(request, "user_add.html", context)
return redirect("/user/list/")

user_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 method="post">{% csrf_token %}<div class="form-group"><label>姓名</label><input type="text" class="form-control" placeholder="姓名" name="user"/></div><div class="form-group"><label>密码</label><input type="text" class="form-control" placeholder="密码" name="pwd"/></div><div class="form-group"><label>年龄</label><input type="text" class="form-control" placeholder="年龄" name="age"/></div><div class="form-group"><label>余额</label><input type="text" class="form-control" placeholder="余额" name="ac"/></div><div class="form-group"><label>入职时间</label><input type="text" class="form-control" placeholder="入职时间" name="ctime"/></div><div class="form-group"><label>性别</label><select class="form-control" name="gd">{% for item in gender_choices %}<option value="{{ item.0 }}">{{ item.1 }}</option>{% endfor %}</select></div><div class="form-group"><label>部门</label><select class="form-control" name="dp">{% for item in depart_list %}<option value="{{ item.id }}">{{ item.title }}</option>{% endfor %}</select></div><button type="submit" class="btn btn-primary">提 交</button></form></div></div></div>
{% endblock %}

views.py

def user_add(request):"""添加用户(原始方式)"""# 拿到部门信息,传到前端if request.method == "GET":context = {'gender_choices': models.UserInfo.gender_choices,"depart_list": models.Department.objects.all()}return render(request, 'user_add.html', context)# 获取用户提交的数据user = request.POST.get('user')pwd = request.POST.get('pwd')age = request.POST.get('age')account = request.POST.get('ac')ctime = request.POST.get('ctime')gender = request.POST.get('gd')depart_id = request.POST.get('dp')# 添加到数据库中models.UserInfo.objects.create(name=user, password=pwd, age=age,account=account, create_time=ctime,gender=gender, depart_id=depart_id)# 返回到用户列表页面return redirect("/user/list/")

4、Django组件:Form 和 ModelForm

我们刚了解了用原始方式实现“新建用户”,我们先回顾一下

新建用户:

  • 原始方式理思路:许多情况下会很麻烦

    - 用户提交数据没有校验。
    - 错误,页面上应该有错误提示(例:用户民未填写)。
    - 页面上,没一个字段都需要我们重新写一遍。数据多了简直爆炸
    - 关联的数据,手动去获取并展示循环展示在页面。 
    

    上面四个问题怎么解决呢?

  • Django组件

    • Form组件(简便,可以解决前三个问题)
    • ModelForm组件(最简便)

4.1、初识Form

我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来。

与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确。如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.。

Django form组件就实现了上面所述的功能。

总结一下,其实form组件的主要功能如下:

  • 生成页面可用的HTML标签
  • 对用户提交的数据进行校验
  • 保留上次输入内容
1、views.py
class MyForm(Form):  # django.Formuser = forms.CharField(widget=forms.Input)pwd = form.CharFiled(widget=forms.Input)email = form.CharFiled(widget=forms.Input)account = form.CharFiled(widget=forms.Input)create_time = form.CharFiled(widget=forms.Input)depart = form.CharFiled(widget=forms.Input)gender = form.CharFiled(widget=forms.Input)def user_add(request):if request.method == "GET":form = MyForm()return render(request, 'user_add.html',{"form":form})
2、user_add.html

以往要写一堆input,一个input还要一堆参数,现在利用Form:

<form method="post">{{ form.user }}{{ form.pwd }}{{ form.email }}<!-- <input type="text"  placeholder="姓名" name="user" /> -->
</form>

其实,还能再简便一点,写个循环(循环form中所有的字段):

<form method="post">{% for field in form%}{{ field }}{% endfor %}
</form>

对比采用原始方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y06jGab6-1645714937058)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20220224161845438.png)]

但这样class MyForm(Form)中的内容还是太繁琐了,一个属性一个属性的去定义

细心的同学可能想到,我们在models.py中已经干过这些事情了

4.2、ModelForm(推荐)

0、models.py
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.DateTimeField(verbose_name="入职时间")depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)gender_choices = ((1, "男"),(2, "女"),)gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
1、views.py
class MyForm(ModelForm): xx = form.CharField*("...")  # ModelForm不仅支持数据库中支持的字段,我们也可以另外自定义class Meta:model = UserInfofields = ["name","password","age","xx"]def user_add(request):if request.method == "GET":form = MyForm()return render(request, 'user_add.html',{"form":form})
2、user_add.html
<form method="post">{% for field in form%}{{ field }}{% endfor %}<!-- <input type="text"  placeholder="姓名" name="user" /> -->
</form>
<form method="post">{{ form.user }}{{ form.pwd }}{{ form.email }}<!-- <input type="text"  placeholder="姓名" name="user" /> -->
</form>

5、新建用户(ModelForm)

补充知识:

class Foo(object):def __str__(self):return "Hello World"obj = Foo()
print(obj)  # 输出对象时,如果想要定制显示的内容,可以借助“__str__”
Hello World进程已结束,退出代码为 0
  • views.py
from django.forms import ModelForm"""新建用户(ModelForm版本)"""class MyForm(ModelForm):# xx = form.CharField*("...")  # ModelForm不仅支持数据库中支持的字段,我们也可以另外自定义class Meta:model = models.UserInfo# fields = ["name", "password", "age", "xx"]fields = ["name", "password", "age", 'account', 'create_time', "gender", "depart"]# 我们可以使用下面的方法去获取各个属性,但有个更方便的方法:重定义_init__# widgets = {#     "name": forms.TextInput(attrs={"class": "form-control"}),#     "password": forms.PasswordInput(attrs={"class": "form-control"}),#     "age": forms.TextInput(attrs={"class": "form-control"}),# }# 重定义_init__# 在前端中,我们使用ModelForm的组件中,前端失去了 class="form-control" 效果,我们可以通过Django控制插件# 循环找到所有的插件,添加了class="form-control"def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)for name, field in self.fields.items():# 如果你不想要某一个属性不使用 class="form-control" 这个效果,如 : password# if name == "password":#     continuefield.widget.attrs = {"class": "form-control", "placeholder": field.label}def user_add(request):form = MyForm()return render(request, 'user_add.html', {"form": form})
  • user_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 method="post">{% csrf_token %}{% for field in form %}<div class="form-group"><label>{{ field.label }}</label>{{ field }}</div>{% endfor %}<button type="submit" class="btn btn-primary">提 交</button></form></div></div></div>{% endblock %}

问题:

在这里插入图片描述

原因:
Department object(1)是 models.py 中 Department 的对象

让他正常显示部门名称,解决方法就是本节开头说的,利用__str__魔法函数

models.py

    def __str__(self):return self.title
depart = models.ForeignKey(verbose_name="部门", to="Department", to_field="id", on_delete=models.CASCADE)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sL9aki5B-1645714937058)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20220224191835012.png)]

效果展示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8gJskpGh-1645714937059)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20220224191940798.png)]

将数据储存至数据库:

def user_add(request):if request.method == "GET":form = MyForm()return render(request, 'user_add.html', {"form": form})# 用户POST提交数据,数据效验(不能为空)# 如果数据合法,提交到数据库form = MyForm(data=request.POST)if form.is_valid():print(form.cleaned_data)# 将数据存储至数据库# 方法一:老套路# models.UserInfo.objects.create(...)# 方法二:ModelFormform.save()return redirect("/user/list/")else:print(form.errors)

效果展示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LxbDHvAp-1645714937059)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20220224192057445.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uabon78t-1645714937060)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20220224192106025.png)]

错误提示

  • user_add.html

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VOjoOmFy-1645714937060)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20220224220829674.png)]

{% 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> {# novalidate : 关闭浏览器帮我们做的校验,用自己的 #}{% csrf_token %}{% for field in form %}<div class="form-group"><label>{{ field.label }}</label>{{ field }}<span style="color: red;">{{ field.errors.0 }}</span> {# 错误信息可能有很多,我们只显示第0个就好了 #}</div>{% endfor %}<button type="submit" class="btn btn-primary">提 交</button></form></div></div></div>{% endblock %}
  • views.py
def user_add(request):if request.method == "GET":form = MyForm()return render(request, 'user_add.html', {"form": form})# 用户POST提交数据,数据效验(不能为空)# 如果数据合法,提交到数据库form = MyForm(data=request.POST)if form.is_valid():print(form.cleaned_data)# 将数据存储至数据库# 方法一:老套路# models.UserInfo.objects.create(...)# 方法二:ModelFormform.save()return redirect("/user/list/")# else:#     print(form.errors)return render(request, 'user_add.html', {"form": form})

把多余的注释都去掉

def user_add(request):if request.method == "GET":form = MyForm()return render(request, 'user_add.html', {"form": form})form = MyForm(data=request.POST)if form.is_valid():form.save()return redirect("/user/list/")return render(request, 'user_add.html', {"form": form})
  • 效果展示:
    提交空数据(这里的错误提示都是ModelForm帮我们默认做好的)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VNS2EIJ6-1645714937060)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20220224221213843.png)]

我们可以自己自定义一下:

比如,名字限制在三位以内

  • views.py / MyForm
class MyForm(forms.ModelForm):name = forms.CharField(min_length=3, label="用户名")

报错改为中文:

  • settings.py
# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans'
  • 效果展示:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G1SmJlQP-1645714937061)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20220224224103529.png)]

这篇关于Django 03 :员工管理【 模板继承 + Form + ModelForm】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/260528

相关文章

基于Python和MoviePy实现照片管理和视频合成工具

《基于Python和MoviePy实现照片管理和视频合成工具》在这篇博客中,我们将详细剖析一个基于Python的图形界面应用程序,该程序使用wxPython构建用户界面,并结合MoviePy、Pill... 目录引言项目概述代码结构分析1. 导入和依赖2. 主类:PhotoManager初始化方法:__in

Django序列化中SerializerMethodField的使用详解

《Django序列化中SerializerMethodField的使用详解》:本文主要介绍Django序列化中SerializerMethodField的使用,具有很好的参考价值,希望对大家有所帮... 目录SerializerMethodField的基本概念使用SerializerMethodField的

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

nvm如何切换与管理node版本

《nvm如何切换与管理node版本》:本文主要介绍nvm如何切换与管理node版本问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录nvm切换与管理node版本nvm安装nvm常用命令总结nvm切换与管理node版本nvm适用于多项目同时开发,然后项目适配no

Redis实现RBAC权限管理

《Redis实现RBAC权限管理》本文主要介绍了Redis实现RBAC权限管理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1. 什么是 RBAC?2. 为什么使用 Redis 实现 RBAC?3. 设计 RBAC 数据结构

mac安装nvm(node.js)多版本管理实践步骤

《mac安装nvm(node.js)多版本管理实践步骤》:本文主要介绍mac安装nvm(node.js)多版本管理的相关资料,NVM是一个用于管理多个Node.js版本的命令行工具,它允许开发者在... 目录NVM功能简介MAC安装实践一、下载nvm二、安装nvm三、安装node.js总结NVM功能简介N

SpringBoot中使用 ThreadLocal 进行多线程上下文管理及注意事项小结

《SpringBoot中使用ThreadLocal进行多线程上下文管理及注意事项小结》本文详细介绍了ThreadLocal的原理、使用场景和示例代码,并在SpringBoot中使用ThreadLo... 目录前言技术积累1.什么是 ThreadLocal2. ThreadLocal 的原理2.1 线程隔离2

Linux内存泄露的原因排查和解决方案(内存管理方法)

《Linux内存泄露的原因排查和解决方案(内存管理方法)》文章主要介绍了运维团队在Linux处理LB服务内存暴涨、内存报警问题的过程,从发现问题、排查原因到制定解决方案,并从中学习了Linux内存管理... 目录一、问题二、排查过程三、解决方案四、内存管理方法1)linux内存寻址2)Linux分页机制3)

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

基于Java实现模板填充Word

《基于Java实现模板填充Word》这篇文章主要为大家详细介绍了如何用Java实现按产品经理提供的Word模板填充数据,并以word或pdf形式导出,有需要的小伙伴可以参考一下... Java实现按模板填充wor编程d本文讲解的需求是:我们需要把数据库中的某些数据按照 产品经理提供的 word模板,把数据