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的简介的更多相关文章

  1. Django之modelform简介

    在django中内置了form类和model类,当页面中的form值和model字段值完全一样时,此时可以通过model生成一个完全一样的form,Django中的modelForm就因此而生. 目标 ...

  2. Django之modelform组件

    一.简介与基本使用 简介:django中的modelform组件同时具有model和form作用,但是耦合度比较高,当项目需要拆分时候就比较困难了,所以在使用modelform时候需要先考虑项目的扩展 ...

  3. Django之ModelForm

    简介 Model + Form ==> ModelForm.model和form的结合体,所以有以下功能: 验证 数据库操作 Form回顾 models.py class UserType(mo ...

  4. Django之Form、ModelForm 组件

    Django之Form.ModelForm 组件 一.Form组件: django框架提供了一个form类,来处理web开发中的表单相关事项.众所周知,form最常做的是对用户输入的内容进行验证,为此 ...

  5. Django—ModelForm

    简介 Model + Form ==> ModelForm.model和form的结合体,所以有以下功能: 验证 数据库操作 Form回顾 models.py class UserType(mo ...

  6. forms组件补充与ModelForm简单使用与cookie与session

    目录 forms组件钩子函数 forms组件字段参数 字段参数 validators详解 choices详解 widget详解 forms组件字段类型 ModelForm简单使用 cookie与ses ...

  7. ASP.NET Core 1.1 简介

    ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...

  8. MVVM模式和在WPF中的实现(一)MVVM模式简介

    MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...

  9. Cassandra简介

    在前面的一篇文章<图形数据库Neo4J简介>中,我们介绍了一种非常流行的图形数据库Neo4J的使用方法.而在本文中,我们将对另外一种类型的NoSQL数据库——Cassandra进行简单地介 ...

随机推荐

  1. PyQt5学习笔记----标准文件打开保存框QFileDialog

    单个文件打开 QFileDialog.getOpenFileName()多个文件打开 QFileDialog.getOpenFileNames() 文件夹选取     QFileDialog.getE ...

  2. Frps 家庭服务器访问解决方案

    100.64.0.0/10运营商级(Carrier-grade)NAT保留IP地址   在一次跟踪路由的网络操作时发现自己路由器下一跳路由节点的IP地址比较奇怪,是100.64.0.1.好奇促使我查询 ...

  3. php 关于时间函数

    1. 设置时区 date_default_timezone_set() 和 putenv() 让时间安全地设置就,输入如下代码: date_default_timezone_set('UTC'); / ...

  4. 异步fifo的Verilog实现

     一.分析 由于是异步FIFO的设计,读写时钟不一样,在产生读空信号和写满信号时,会涉及到跨时钟域的问题,如何解决? 跨时钟域的问题:由于读指针是属于读时钟域的,写指针是属于写时钟域的,而异步FIFO ...

  5. Python3学习之路~5.8 shelve模块

    shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式 import shelve import datetime name = [& ...

  6. Oracle(2)之多表查询&子查询&集合运算

    多表查询 笛卡尔积 同时查询多张表时,每张表的每条数据都要和其它表的每条数据做组合.如下栗子,我们发现产生的总记录数是 56 条,还发现 emp 表是 14 条,dept 表是 4 条,56 条正是 ...

  7. 前端框架之Vue(1)-第一个Vue实例

    vue官方文档 知识储备 es6语法补充 let 使用 var 声明的变量的作用域是全局. { var a = 1; } console.info(a); 例1: var arr = []; for ...

  8. element

    <el-table-column label="地址" prop="address"> <template slot-scope=" ...

  9. HBuilder 自动整理代码格式快捷键设置

    工具 ->选项

  10. (转)Mysql LIMIT如何正确对其进行优化

    以下的文章主要是对Mysql LIMIT简单介绍,我们大家都知道LIMIT子句一般是用来限制SELECT语句返回的实际行数.LIMIT取1个或是2个数字参数,如果给定的是2个参数,第一个指定要返回的第 ...