modelform的简介
Form介绍
我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来。
与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确。如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.。
Django form组件就实现了上面所述的功能。
总结一下,其实form组件的主要功能如下:
- 生成页面可用的HTML标签
- 对用户提交的数据进行校验
- 保留上次输入内容
普通方式手写图书管理系统的增加书籍和编辑书籍功能
views.py,

def book_list(request):
book_list = models.Book.objects.all()
return render(request, "book_list.html", {"book_list": book_list}) def add_book(request):
# 获取前端提交的数据
if request.method == "POST":
title = request.POST.get("title")
price = request.POST.get("price")
publish_date = request.POST.get("publish_date")
publisher = request.POST.get("publisher")
authors = request.POST.get("authors")
# 数据库中的数据
book_obj = models.Book.objects.create(
title=title,
price=price,
publish_date=publish_date,
publisher_id=publisher,
)
book_obj.authors.add(*authors)
return redirect("/book_list/")
publisher_list = models.Publisher.objects.all()
author_list = models.Author.objects.all()
return render(request,"add_book.html",{"publisher_list":publisher_list,"author_list":author_list}) # 编辑出版社
def edit_book(request, pk):
book_obj = models.Book.objects.filter(id=pk).first()
if request.method == "POST":
title = request.POST.get("title")
price = request.POST.get("price")
publish_date = request.POST.get("publish_date")
publisher = request.POST.get("publisher")
authors = request.POST.getlist("authors") # 什么时候用getlist/多选的checkbox也是
book_obj.title = title
book_obj.price = price
book_obj.publish_date = publish_date
book_obj.publisher_id = publisher
book_obj.save()
book_obj.authors.set(authors)
return redirect("/book_list/")
publisher_list = models.Publisher.objects.all()
author_list = models.Author.objects.all()
return render(request, "edit_book.html", locals())

book_list.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>书籍列表</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/css/bootstrap.css">
<link rel="stylesheet" href="/static/css/pub.css">
</head>
<body>
{% include 'nav.html' %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li><a href="/publisher/">出版社管理 <span class="sr-only">(current)</span></a></li>
<li class="active"><a href="/book_list/">书籍管理</a></li>
<li><a href="/author_list/">作者管理</a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main"> <div class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title">书籍列表</h2>
</div> <div class="panel-body">
<div class="row">
<div class="col-lg-3">
<div class="input-group">
<input type="text" class="form-control" placeholder="搜索">
<span class="input-group-btn">
<button class="btn btn-primary" type="button">Go</button>
</span>
</div><!-- /input-group -->
</div> <div class="pull-right col-lg-1">
<a href="/add_book/" class="btn btn-info ">添加</a>
</div>
</div>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>序号</th>
<th>ID</th>
<th>标题</th>
<th>价格</th>
<th>出版日期</th>
<th>出版社</th>
<th>作者</th>
</tr>
</thead>
<tbody>
{% for book in book_list %} <tr>
<td>{{ forloop.counter }}</td>
<td>{{ book.id }}</td>
<td>{{ book.title }}</td>
<td>{{ book.price }}</td>
<td>{{ book.publish_date }}</td>
<td>{{ book.publisher.name }}</td>
<td>
{% for author in book.authors.all %}
{% if forloop.last %}
{{ author.name }}
{% else %}
{{ author.name }} |
{% endif %}
{% endfor %}
</td>
<td>
<a href="/del_book/{{ book.id }}" class="btn btn-danger btn-sm">删除</a>
<a href="/edit_book/{{ book.id }}" class="btn btn-warning btn-sm">编辑</a>
</td>
</tr> {% endfor %} </tbody>
</table>
</div> <div class="pull-right">
<nav aria-label="...">
<ul class="pagination">
<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a>
</li>
<li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
<li><a href="#" aria-label="Next"><span aria-hidden="true">»</span></a></li>
</ul>
</nav>
</div> </div>
</div>
</div>
</div>
</div> </body>
</html>
edit_book.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编辑书籍</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/css/bootstrap.css"> </head>
<body>
{% include 'nav.html' %}
<div class="container" style="margin-top: 100px">
<div class="row">
<div class="col-lg-6 col-lg-offset-3">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">编辑书籍</h3>
</div> <div class="panel-body"> <div class="row">
<form class="form-horizontal" method="post" action="">
{% csrf_token %}
<input type="text" name="id" value="{{ edit_book.id }}" style="display: none">
<div class="form-group">
<label for="publisher" class="col-sm-2 control-label">名称</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="publisher" name="title"
value="{{ book_obj.title }}">
</div>
</div>
<div class="form-group">
<label for="price" class="col-sm-2 control-label">价格</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="price" name="price"
value="{{ book_obj.price }}">
</div>
</div>
<div class="form-group">
<label for="date" class="col-sm-2 control-label">日期</label>
<div class="col-sm-9">
<input type="date" class="form-control" id="date" name="date"
value="{{ book_obj.publish_date|date:'Y-m-d' }}">
</div>
</div>
<div class="form-group">
<label for="publisher" class="col-sm-2 control-label">出版社</label>
<div class="col-sm-9">
<select name="publish" id="" class="form-control">
{% for publish in publisher_list %}
{% if publish.id == book_obj.publisher_id %}
<option value="{{ publish.id }}" selected>{{ publish.name }}</option>
{% else %}
<option value="{{ publish.id }}">{{ publish.name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label for="publisher" class="col-sm-2 control-label">作者</label>
<div class="col-sm-9">
<select name="authors" id="" class="form-control">
{% for author in author_list %}
{% if author in book_obj.authors.all %}
<option selected value="{{ author.id }}">{{ author.name }}</option>
{% else %}
<option value="{{ author.id }}">{{ author.name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div> <div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">提交</button>
</div>
</div>
<div class="row">
<p class="text-center text-danger">{{ err_msg }}</p> </div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
add_book.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加书籍</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/css/bootstrap.css"> </head>
<body>
{% include 'nav.html' %}
<div class="container" style="margin-top: 100px">
<div class="row">
<div class="col-lg-6 col-lg-offset-3">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">增加书籍</h3>
</div> <div class="panel-body"> <div class="row">
<form class="form-horizontal" method="post" action="">
{% csrf_token %}
<div class="form-group">
<label for="publisher" class="col-sm-2 control-label">名称</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="publisher" name="title">
</div>
</div>
<div class="form-group">
<label for="price" class="col-sm-2 control-label">价格</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="price" name="price">
</div>
</div>
<div class="form-group">
<label for="publish_date" class="col-sm-2 control-label">日期</label>
<div class="col-sm-9">
<input type="date" class="form-control" id="publish_date" name="publish_date">
</div>
</div>
<div class="form-group">
<label for="publisher" class="col-sm-2 control-label">出版社</label>
<div class="col-sm-9">
<select name="publisher" id="" class="form-control"> {% for publish in publisher_list %}
<option value="{{ publish.id }}">{{ publish.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label for="authors" class="col-sm-2 control-label">作者</label>
<div class="col-sm-9">
<select name="authors" id="" class="form-control"> {% for author in author_list %}
<option value="{{ author.id }}">{{ author.name }}</option>
{% endfor %}
</select>
</div>
</div> <div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">提交</button>
</div>
</div>
<div class="row">
<p class="text-center text-danger">{{ err_msg }}</p> </div>
</form>
</div>
</div>
</div>
</div>
</div>
</div> </body>
</html>
nav.html:
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">图书管理系统</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Dashboard</a></li>
<li><a href="#">Settings</a></li>
<li><a href="#">Profile</a></li>
<li><a href="#">Help</a></li>
</ul>
<form class="navbar-form navbar-right">
<input type="text" class="form-control" placeholder="Search...">
</form>
</div>
</div>
</nav>
2、用form组件实现增改查:
要带入from django.forms.models import model_to_dict实现默认值的显示:
views.py代码:
# y用form组件的增加书籍
def add_book1(request):
# 获取前端提交的数据
if request.method == "POST":
# 不用一步一步写了,直接获取就行了
form_obj = forms.BookForm(request.POST)
# 进行校验
if form_obj.is_valid():
# 因为authors是关联表里边的,不是书籍这张表里的,所以要把这个弹出去
authors = form_obj.cleaned_data.pop("authors")
# 创建的时候,需要所有数据打散
book_obj = models.Book.objects.create(**form_obj.cleaned_data)
book_obj.authors.add(*authors)
return redirect("/book_list/")
publisher_list = models.Publisher.objects.all()
author_list = models.Author.objects.all()
form_obj = forms.BookForm()
return render(request, "add_book1.html", locals()) # y用form组件的编辑书籍
def edit_book1(request, pk):
book_obj = models.Book.objects.filter(id=pk).first()
obj_dict = model_to_dict(book_obj)
print(obj_dict) # 能把你想要修改的那个对象获取出来
if request.method == "POST":
form_obj = forms.BookForm(request.POST)
if form_obj.is_valid():
title = form_obj.cleaned_data.get("title")
price = form_obj.cleaned_data.get("price")
publish_date = form_obj.cleaned_data.get("publish_date")
publisher = form_obj.cleaned_data.get("publisher")
authors = form_obj.cleaned_data.get("authors")
book_obj.title = title
book_obj.price = price
book_obj.publish_date = publish_date
book_obj.publisher_id = publisher
book_obj.save()
book_obj.authors.set(authors)
return redirect("/book_list/")
form_obj = forms.BookForm(initial=obj_dict) # 这个就是你原来的默认值
publisher_list = models.Publisher.objects.all()
author_list = models.Author.objects.all()
return render(request, "edit_book1.html", locals())
html代码,编辑和增加都一样:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加书籍</title>
</head>
<body> <form action="" method="post">
{% csrf_token %}
{% for filed in form_obj %}
<p>
{{ filed.label }}
{{ filed }}
</p>
{% endfor %}
{{ form_obj.errors }}
<p>
<input type="submit">
</p>
</form>
</body>
</html>
form.py中的一个属性也要改变:
class BookForm(forms.Form):
title = forms.CharField(max_length=32, label="书名")
price = forms.DecimalField(max_digits=5, decimal_places=2)
publish_date = forms.DateField( # 这个是因为返回的页面要是date格式的
widget=forms.widgets.DateInput(
attrs={"type": "date"}
)
)
publisher = forms.ModelChoiceField(
# choices=models.Publisher.objects.all().values_list("id","name"),
# widget=forms.widgets.Select(), # 单选
queryset=models.Publisher.objects.all() # 单选这个是和你模型绑定
)
authors = forms.ModelMultipleChoiceField(
# choices=models.Author.objects.all().values_list("id", "name"),
# widget=forms.widgets.SelectMultiple(), # 多选
queryset=models.Author.objects.all() # 单选这个是和你模型绑定
)
form组件中遇到的知识点:
用form组件实现增改查
1. 在页面展示html时
{% for filed in form_obj %}
<p>
{{ filed.label }}
{{ filed }}
</p>
{% endfor %} 2. ChoiceField -> ModelChoiceField -> ModelMultipleChoiceField
1. ModelChoiceField
生成select标签
option选项是从queryset中获取的
2. ModelMultipleChoiceField
生成多选的select标签
option选项是从queryset中获取 3. form_obj如何设置初始化的值
from django.forms.models import model_to_dict --> Django 内置的把ORM对象转换成字典的工具函数
obj_dict = model_to_dict(book_obj)
form_obj = forms.BookForm(initial=obj_dict)
3.使用modelform,使用这个简单明了,就是在form.py写:
from django import forms
from app01 import models class BookForm(forms.Form):
title = forms.CharField(max_length=32, label="书名")
price = forms.DecimalField(max_digits=5, decimal_places=2)
publish_date = forms.DateField( # 这个是因为返回的页面要是date格式的
widget=forms.widgets.DateInput(
attrs={"type": "date"}
)
)
publisher = forms.ModelChoiceField(
# choices=models.Publisher.objects.all().values_list("id","name"),
# widget=forms.widgets.Select(), # 单选
queryset=models.Publisher.objects.all() # 单选这个是和你模型绑定
)
authors = forms.ModelMultipleChoiceField(
# choices=models.Author.objects.all().values_list("id", "name"),
# widget=forms.widgets.SelectMultiple(), # 多选
queryset=models.Author.objects.all() # 单选这个是和你模型绑定
) # modelform
class BookModelForm(forms.ModelForm): class Meta:
# 告诉Django这个form类和那个model类对应
model = models.Book
# 告诉Django这个form类里面有哪些字段
fields = "__all__" # 所有字段
widgets = {
"publish_date": forms.widgets.DateInput(
attrs={
"type": "date"
}
)
}
labels = {
"title": "书名",
"price": "价格"
}
views.py代码:
# y用modelform的增加书籍
def add_book2(request):
# 获取前端提交的数据
if request.method == "POST":
# 不用一步一步写了,直接获取就行了
form_obj = forms.BookModelForm(request.POST)
# 进行校验
if form_obj.is_valid():
form_obj.save()
return redirect("/book_list/")
form_obj = forms.BookModelForm()
return render(request, "add_book1.html", locals()) # y用modelform的编辑书籍
def edit_book2(request, pk):
book_obj = models.Book.objects.filter(id=pk).first()
if request.method == "POST":
form_obj = forms.BookModelForm(request.POST, instance=book_obj)
if form_obj.is_valid():
form_obj.save()
return redirect("/book_list/")
form_obj = forms.BookModelForm(instance=book_obj) # 实例:直接传,不需要转成字典类型
return render(request, "edit_book1.html", locals())
modelform的简介的更多相关文章
- Django之modelform简介
在django中内置了form类和model类,当页面中的form值和model字段值完全一样时,此时可以通过model生成一个完全一样的form,Django中的modelForm就因此而生. 目标 ...
- Django之modelform组件
一.简介与基本使用 简介:django中的modelform组件同时具有model和form作用,但是耦合度比较高,当项目需要拆分时候就比较困难了,所以在使用modelform时候需要先考虑项目的扩展 ...
- Django之ModelForm
简介 Model + Form ==> ModelForm.model和form的结合体,所以有以下功能: 验证 数据库操作 Form回顾 models.py class UserType(mo ...
- Django之Form、ModelForm 组件
Django之Form.ModelForm 组件 一.Form组件: django框架提供了一个form类,来处理web开发中的表单相关事项.众所周知,form最常做的是对用户输入的内容进行验证,为此 ...
- Django—ModelForm
简介 Model + Form ==> ModelForm.model和form的结合体,所以有以下功能: 验证 数据库操作 Form回顾 models.py class UserType(mo ...
- forms组件补充与ModelForm简单使用与cookie与session
目录 forms组件钩子函数 forms组件字段参数 字段参数 validators详解 choices详解 widget详解 forms组件字段类型 ModelForm简单使用 cookie与ses ...
- ASP.NET Core 1.1 简介
ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...
- MVVM模式和在WPF中的实现(一)MVVM模式简介
MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...
- Cassandra简介
在前面的一篇文章<图形数据库Neo4J简介>中,我们介绍了一种非常流行的图形数据库Neo4J的使用方法.而在本文中,我们将对另外一种类型的NoSQL数据库——Cassandra进行简单地介 ...
随机推荐
- windows安装nginx并存放静态资源
1.将nginx-windows.zip下载下来,然后点击nginx.exe 如果一闪而过并且打开网页输入localhost显示无法访问,打开error.log文件:No mapping for th ...
- [资料] Ceph存储系统,关于Redhat和Suse企业版存储知识汇总
版权声明:很多其它内容,请关注[架构师技术联盟]公众号 https://blog.csdn.net/BtB5e6Nsu1g511Eg5XEg/article/details/81117091 wx_f ...
- UE4程序及资源加密保护方案
UnrealEngine4外壳加密 . Virbox Protector 解决代码反汇编和反dump代码,解决软件盗版与算法抄袭. 虚幻引擎4是由游戏开发者为开发游戏而制作的.完整的游戏开发工具套件. ...
- [django]django 3种返回json方法
django 3种返回json方法 1.手动组装字典返回 from django.http import JsonResponse, HttpResponse from django.shortcut ...
- NeuroNER+brat工具学习
1.Brat:http://brat.nlplab.org/ 能够进行直觉标注.命名实体识别.关系标注.分块.共存标注.二元关系标注等(药物与药物).时间标注. 但是这个安装好麻烦啊... 2.
- VS Code的golang开发配置 之 代码提示
之前用VS Code的时候,发现自己的代码的提示一直不好,换用JetBrain的Goland的代码提示是好了,但是比较占用资源.在网上找了一些资料,发现很多人也是遇到第三方或者自己的代码无法提示的情况 ...
- [LeetCode] 系统刷题6_Linked List
1. Dummy Node 2. Basic skills [LeetCode] 206. Reverse Linked List_Easy tag: Linked List 2. Fast slow ...
- [Java] Header checkBox in Jtable
The reference is from here. 在Jtable里面我们可能会有checkbox, 而有时候我们有很多checkbox需要同时check或者同时uncheck的时候, 如果有一个 ...
- \r\n 回车换行浅析
\r \ 10 x0a return \n \ x0d newline Unix系统里,每行结尾只有“<换行>”,即“\n”: Windows系统里面,每行结尾是“<回车>&l ...
- C# 抽象类、抽象属性、抽象方法
抽象类往往用来表征对问题领域进行分析.设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象. 下面我们以水果为例,首先定义抽象类Fruit,抽象类中有公共属性vendor,抽象属 ...