平时自己在手写前端form表单的时候很复杂繁琐(我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确。如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.。),但是Django的form表单帮你简化了这一个流程也帮你做了这样的事情,
1.生成页面可用的html标签
2.对传递到浏览器的数据进行校验
3.保留上次输入的数据(如果有错误数据没有提交成功。)
首先我们先展示一下使用普通的的html form表单提交数据的流程。
这是book_add.html的代码。这是我们手写的form表单
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加书籍</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
<p>书名<input type="text" name="book"><br></p>
<p>价格<input type="text" name="price"><br></p>
<p>
出版社
<select name="publish" id="">
{% for publish in publish_list %}
<option value="{{ publish.pk }}">{{ publish.name }}</option>
{% endfor %}
</select><br>
</p>
<p>
作者
<select name="author" id="" multiple="multiple">
{% for author in author_list %}
<option value="{{ author.pk }}">{{ author.name }}</option>
{% endfor %}
</select>
</p>
<p>日期 <input type="date" name="date"></p>
<input type="submit">
</form>
</body>
</html>
views.py对应的源码:
def book_add(request):
# 进行提交数据
if request.method == "POST":
# 获取前端传递过来的name,publish, price, author, date
name = request.POST.get('book')
publish = request.POST.get('publish')
price = request.POST.get('price')
author = request.POST.getlist('author')
date = request.POST.get('date')
# book_obj = Book.objects.create(title=title, price=price, date=date, publish_id=publish_id)
# book_obj.authors.add(*author_pk_list)
# 把数据存储进Book表里面
book_list = Books.objects.create(name=name, publish_id=publish, date=date, price=price)
book_list.author.add(*author)
return redirect('/book/books/')
# 获取所有的出版社obj和作者obj传递到前端
publish_obj = Publish.objects.all()
author_obj = Author.objects.all()
return render(request, 'book_add.html', {'publish_list': publish_obj, 'author_list': author_obj})
这是手写的代码,这里还没有写前端的校验代码,就已经够繁琐的了。接下来就看看使用Django的form组件的效果吧!
Django 的form组件使用
Django的form组件使用。你最好在你的app下面专门创建一个forms.py 文件用来专门储存form组件有关的代码。
forms.py代码如下:
# -*- coding: utf-8 -*-
# @Time : 2019/3/28 下午 2:02
# @Author : lh
# @Email : 2472@qq.com
# @File : forms.py
# @Software: PyCharm
from django import forms
from django.forms import widgets
from .models import Publish, Author
class BookForm(forms.Form):
name = forms.CharField(
max_length=16,
min_length=8,
label="书名",
error_messages={
'required': '不能为空!'
}
)
price = forms.DecimalField(max_digits=8, decimal_places=2, label="价格")
date = forms.CharField(widget=widgets.TextInput(attrs={"type": "date"}), label="日期")
# publish = forms.ChoiceField(choices=(Books.objects.all().values_list("id", 'name')))
publish = forms.ModelChoiceField(queryset=Publish.objects.all())
author = forms.ModelMultipleChoiceField(queryset=Author.objects.all())
写完后就该在自己的views代码里面添加使用form了,使用form来生成form里面的代码段了。
views.py
def book_add(request):
# 进行数据提交
if request.method == "POST":
# 把浏览器提交的数据交给form组件进行校验
forms = BookForm(request.POST)
# 如果通过校验
if forms.is_valid():
print(forms.cleaned_data)
name = forms.cleaned_data.get('name')
publish = forms.cleaned_data.get('publish')
price = forms.cleaned_data.get('price')
author = forms.cleaned_data.get('author')
print(author)
date = forms.cleaned_data.get('date')
# book_obj = Book.objects.create(title=title, price=price, date=date, publish_id=publish_id)
# book_obj.authors.add(*author_pk_list)
# 把通过校验的数据存储进表
book_list = Books.objects.create(name=name, publish=publish, date=date, price=price)
book_list.author.add(*author)
return redirect('/book/books/')
# 生成form实例然后传递给前端
forms = BookForm()
return render(request, 'book_add.html', {"forms": forms})
这里面只是一个简单的逻辑。
接下来在看看html那边的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加书籍</title>
</head>
<body>
<form action="" method="post" novalidate>
{% csrf_token %}
<div>
{{ forms.name.label }}
{{ forms.name }}{{ forms.name.errors.0 }}
</div>
<div>
{{ forms.price.label }}
{{ forms.price }}
</div>
<div>
{{ forms.date.label }}
{{ forms.date }}
</div>
<div>
{{ forms.publish.label }}
{{ forms.publish }}
</div>
<div>
{{ forms.author.label }}
{{ forms.author }}
</div>
<input type="submit">
</form>
</body>
</html>
从这里可以看出html端的代码也是比较简洁的。通过模板生成我们需要的一些输入框之类的。还可以进行数据的校验呢。但是有些form组件也是做起来也没那么方便。因为form也没有将数据和自身结合在一起。这时候就产生了一个更加高级的东西了。那就是modelform了。
modelform的使用:
modelform就是model和form结合在一起了。使用model来生成form。进行生成html代码。
这是forms里面的代码。
from django.forms import ModelForm
from django.forms import widgets as wid
from .models import Publish, Author, Books
class BookForm(ModelForm):
class Meta:
# 结合哪一张表
model = Books
# 生成多少个对应的代码,"__all__"是所有,如果是指定就要使用列表储存起来。
fields = "__all__"
labels = {
'name': '书籍名称',
'price': '价格',
'date': '时间',
'publish': '出版社',
'author': '作者',
}
widgets = {
'date': wid.TextInput(attrs={'type': 'date', })
}
上面的代码具有和form一样的作用。而且比form简洁、
现在我们再来看看 views里面的代码:
def book_add(request):
# 如果是进行数据提交
if request.method == "POST":
# 对modelform的使用。传递浏览器过来的数据进去。
forms = BookForm(request.POST)
# 如果数据通过校验
if forms.is_valid():
# 直接保存在数据库里面。因为modelform是model和form的结合一般。可以直接操作表
forms.save()
return redirect('/book/books/')
forms = BookForm()
return render(request, 'book_add.html', {"forms": forms})
html的代码如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加书籍</title>
</head>
<body>
{#{% include "add_edit.html" %}#}
<form action="" method="post" novalidate>
{% csrf_token %}
<div>
{{ forms.name.label }}
{{ forms.name }}{{ forms.name.errors.0 }}
</div>
<div>
{{ forms.price.label }}
{{ forms.price }}
</div>
<div>
{{ forms.date.label }}
{{ forms.date }}
</div>
<div>
{{ forms.publish.label }}
{{ forms.publish }}
</div>
<div>
{{ forms.author.label }}
{{ forms.author }}
</div>
<input type="submit">
</form>
</body>
</html>
这个就是modelform的简单使用了.。