一 form
1. form的作用
1. 生成HTML代码
2. 帮我们做数据有效性的校验
3. 保留上次输入内容,显示错误提示
2. form组件校验数据有效性
1. 内置的校验规则
1. require=True 该字段必填
2. max_length 该字段的最大长度
3. min_length 该字段的最小长度
2. 自定义校验规则
1. 如手机号的格式 利用内置的正则校验器
from django.core.validators import RegexValidator
validators=[RegexValidator(r'^1[356789]\d{9}$', "手机号码格式不正确")],
3. 使用钩子函数做校验
1. 局部钩子(hook)
在form类内部定义一个 clean_字段名() 方法
例子
#自定义一个局部钩子函数含有alex的关键字不能提交
def clean_title(self):
value=self.cleaned_data.get("title") #获取书名
if "alex" in value:
raise ValidationError("ALEX以备和谐")
else:
return value
2. 全局钩子
在form类内部定义一个 clean() 方法
4. form组合如何给html标签设置默认值
1. 每一个字段设置默认值
initial="默认值"
实例:关于使用form的例子,使用form之前可以自己写一个单独的form类,我这里一添加book为例:
1 form.py


1 from django import forms
2 from app01 import models
3 from django.core.exceptions import ValidationError #注册功能
4 from django.core.validators import RegexValidator # 检验手机号码是否正确
5
6 # 自己定义一个form类
7 class BookForm(forms.Form):
8 title=forms.CharField(
9 max_length=12,
10 min_length=2,
11 # 如果想让网页显示中文就加上label
12 label="书名",
13 initial="填写书名",
14 # 给tttle生成的input标签加上一个class类
15 widget=forms.widgets.TextInput(attrs={"class":"form-control"})
16 )
17 publisher_date=forms.DateField(
18 label="出版日期",
19 # widget 插件
20 widget=forms.widgets.DateInput(attrs={"type":"date","class":"form-control"})
21 )
22 phone=forms.CharField(
23 max_length=11,
24 validators=[RegexValidator(r'^1[356789]\d{9}$',"手机号码格式不正确")], # 限制手机号格式
25 widget = forms.widgets.TextInput(attrs={"class": "form-control"})
26 )
27 # 用modelchoicefield可以实时显示到页面上面当数据库增加的时候
28 publisher = forms.ModelChoiceField(
29 queryset=models.Publisher.objects.all(),
30 widget=forms.widgets.Select(attrs={"class": "form-control"}),
31 )
32 authors=forms.ModelMultipleChoiceField(
33 queryset=models.Author.objects.all(),
34 widget=forms.widgets.SelectMultiple(attrs={"class": "form-control"})
35 )
36 #自定义一个局部钩子函数含有alex的关键字不能提交
37 def clean_title(self):
38 value=self.cleaned_data.get("title") #获取书名
39 if "alex" in value:
40 raise ValidationError("ALEX以备和谐")
41 else:
42 return value
2 views.py里面的配置做了一些改变
首先要导入你刚才自己定义的BookForm
from app01.forms import BookForm
def add_book(request):
form_obj=BookForm()
if request.method=="POST":
form_obj=BookForm(request.POST)
if form_obj.is_valid(): #做数据有效性校验
# 因为有多对多的字段,所以需要额外处理
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/")
return render(request,"add_book.html",locals())
编辑功能
def edit_book(request,pk):
book_obj=models.Book.objects.filter(id=pk).first()
from django.forms import model_to_dict # 导入这个模块
book_dict=model_to_dict(book_obj) # 转换成字典格式
book_dict["publisher_date"]=book_obj.publisher_date.strftime("%Y-%m-%d") # 时间转换成字符串格式
form_obj=BookForm(book_dict)
if request.method=="POST":
form_obj=BookForm(request.POST) # 接受用户传来的数据
if form_obj.is_valid(): # 判断数据是否正常
book_obj.title=form_obj.cleaned_data.get("title")
book_obj.publisher_id=form_obj.cleaned_data.get("publisher_date")
book_obj.publisher_id=form_obj.cleaned_data.get("publisher")
book_obj.save()
book_obj.authors.set(form_obj.cleaned_data.get("authors"))
return redirect("/book_list")
return render(request,"edit_book.html",locals())
3 html里面也做了一些改变:(一些类的名字也都在forms里面给自动添加上了)


1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>添加书籍</title>
6 <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
7 </head>
8 <body>
9 <div class="container">
10 <div class="row">
11 <div class="col-md-8 col-md-offset-2">
12 <h1>添加书籍</h1>
13 <form action="" method="post" novalidate autocomplete="off">
14 {% for field in form_obj %}
15 <div class="form-group">
16 <label for="{{ field.id_for_label }}">{{ field.label }}</label>
17 {{ field }}
18 <p>{{ field.errors.0 }}</p>
19
20 </div>
21 {% endfor %}
22 <input type="submit" class="btn btn-success">
23 </form>
24
25 </div>
26
27 </div>
28
29 </div>
30
31 </body>
32 </html>
二 model form
1. 必须继承forms.ModelForm
2. class Meta:
model = "一对一关联的model类名"
fields = "__all__"
3. 实例化
1. BookModelForm(instance=book_obj)
2. BookModelForm(request.POST, instance=book_obj)
4. form_obj.save()
要想使用modelform,也必须先写个modelform
modelform例子:
1 modelform.py
from django import forms
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from app01 import models
class BookModelForm(forms.ModelForm):
class Meta:
model=models.Book
fields="__all__" #model类里面所有的字段都展示
# fields="title" # 指定展示某些字段
# exclude=["title"] # 除了知道字段,其他字段都展示
# labels可以设置在网页上面显示的文字
labels={
"title":"书名",
"publisher_date":"创建日期",
"phone":"手机号",
"publisher":"出版社",
"authors":"作者",
}
widgets={ # 设置每个字段的插件信息
"title": forms.widgets.TextInput(attrs={"class": "form-control"}),
"phone": forms.widgets.TextInput(attrs={"class": "form-control"}),
"publisher": forms.widgets.Select(attrs={"class": "form-control"}),
"authors": forms.widgets.SelectMultiple(attrs={"class": "form-control"}),
}
error_messages = { # 设置每个字段的报错提示信息
"publisher": {
"required": "必须给我选一个出版社!"
},
"authors":{
"required":"必须选择一个作者"
}
}
2 views.py里面设置:
要先导入你刚才写的那个
from app01.forms import BookModelForm
添加
def add_book(request):
form_obj = BookModelForm()
if request.method == "POST":
form_obj = BookModelForm(request.POST)
if form_obj.is_valid():
form_obj.save()
return redirect("/book_list/")
return render(request, "add_book.html", locals())
编辑
def edit_book(request, pk):
book_obj = models.Book.objects.filter(id=pk).first()
print("我是book_obj", book_obj)
# instance实例
form_obj = BookModelForm(instance=book_obj) # 实例化的form_obj
if request.method == "POST":
# 获取用户提交过来的数据,用request.POST传过来的数据去更新book_obj这本书
form_obj = BookModelForm(request.POST, instance=book_obj)
if form_obj.is_valid():
form_obj.save()
return redirect("/book_list/")
return render(request, "edit_book.html", locals())
3 html编辑和添加内容都是一样的


1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>添加书籍</title>
6 <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
7 </head>
8 <body>
9
10 <div class="container">
11 <div class="row">
12 <div class="col-md-8 col-md-offset-2">
13 <h1>添加书籍</h1>
14
15 <form action="" method="post" novalidate autocomplete="off">
16 {% csrf_token %}
17
18 {% for field in form_obj %}
19 <div class="form-group">
20 <label for="{{ field.id_for_label }}">{{ field.label }}</label>
21 {{ field }}
22 <p>{{ field.errors.0 }}</p>
23 </div>
24 {% endfor %}
25 <input type="submit" class="btn btn-success">
26 </form>
27 </div>
28 </div>
29 </div>
30
31 </body>
32 </html>