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. java读取配置文件的信息

    1. 首先,工程结构如下: 注:a. 蓝色标注的两个文件是和com包平级的,都在src下.EnnNotificationPushProxy.ini是这个工程的配置文件,log4j.properties ...

  2. laravel用crud修改产品items-新建resource controller和routing

    前面我们创建了laravel简单的items产品api,但是需要在数据库添加,如何在网页上直接添加呢?我们可以用view来操作crud(增加Create.读取查询Retrieve.更新Update和删 ...

  3. oracle安装---yum.sh

    !#/bin/bash yum install binutils* -yyum install compat* -yyum install elfutils* -yyum install gcc* - ...

  4. JavaScript基础学习2

    /* 1.把函数作为参数.匿名函数作为参数传递到函数 */ function dogEat(food) { console.log("dog eat " + food); } fu ...

  5. VS Code的golang开发配置 之 代码提示

    之前用VS Code的时候,发现自己的代码的提示一直不好,换用JetBrain的Goland的代码提示是好了,但是比较占用资源.在网上找了一些资料,发现很多人也是遇到第三方或者自己的代码无法提示的情况 ...

  6. [Java] Frequently used method or solutions for issues

    模板: Split string into parts based on new line in java Solution:   Reference is here. 1) get out of t ...

  7. js图的数据结构处理----普里姆算法

    //求加权无向连通图的MST的贪心算法 //最小树,最小路径联通各个点 function PRIM(){ var graph = [ [], [undefined,Infinity, 23 ,Infi ...

  8. leetcode 198打家劫舍

    讲解视频见刘宇波leetcode动态规划第三个视频 记忆化搜索代码: #include <bits/stdc++.h> using namespace std; class Solutio ...

  9. iOS UI基础-9.1 UITableView 团购

    概述 接下来,我们要做的是团购界面的设计,最张要实现的效果图及项目结构图      团购数据的展示 思路: 系统自带的tableCell不能展示三个文本,不能满足条件,自定义tableCell 每一个 ...

  10. 当我的url请求会变成jsp页面路径时的解决办法

    @RequestMapping(value="shippingOrder") $.post("/ezsh/orderAd/shippingOrder",para ...