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. kali蓝牙连接

    http://blog.csdn.net/hailangnet/article/details/47723181 http://www.aiuxian.com/article/p-3012084.ht ...

  2. VS2013 opencv配置

    有三个地方需要配置,在配置之前首先要将platform配置好,下面的例子是x64 Release的“ 然后需要将include.lib的路径配置好 然后将dll拷贝至编译生成的Release文件夹中即 ...

  3. JavaScript, DOM查找元素

    1.document.getElementById("id"); => IE8 及较低版本不区分ID的大小写 => IE7及较低版本中表单元素的name特性和ID都会被 ...

  4. 写一致性原理以及quorum机制

    (1)consistency,one(primary shard),all(all shard),quorum(default)我们在发送任何一个增删改操作的时候,比如 PUT /index/type ...

  5. 火币网API文档——REST API 错误码

    错误码 行情 API 错误码 错误码 描述 bad-request 错误请求 invalid-parameter 参数错 invalid-command 指令错 code 的具体解释, 参考对应的er ...

  6. 网络传输--UDP

    UDP网络编程 一.优缺点 二.套接字socket 三.类型转换 四.UDP发收数据 五.广播和聊天器案例 回到顶部 一.优缺点 UDP : 无连接 (发送端无需确认接收端是否收到), 其主要用途为音 ...

  7. .net core中常用的属性

    //IsNullOrWhiteSpace()判断字符串是否为空 指示指定的字符串是 null.空还是仅由空白字符组成,如果字符串的空白String a="  ";IsNullOrE ...

  8. 大牛推荐的10本学习 Python 的好书

    Python:蛇亚目蟒科,主要包括分布于非洲及亚洲的无毒蟒蛇. Python:Richard Clabaugh拍摄的恐怖电影,2000年发行. Python:澳大利亚汽车公司. Python:英国偶发 ...

  9. 合理利用配置不同的机器资源做redis cluster的server

    Redis cluster可以使用不同配置的机器学习因为我们可以手动调整不同的机器所承担的slot的个数,这样内存小CPU相对少的机器应该承担更少的slots

  10. 删除docker下的镜像

    先显示一下docker中的镜像 删除镜像 先停止这个容器 删除容器 再删除镜像就可以啦!