web-Django-16-Form验证

  • 目录
  • 基本功能
  • 基本使用
  • 常用字段
  • 常用插件
  • 总结

这篇博客记录Django Form功能的学习,链接请参考Django Form武佩齐权威博客

基本功能

  • Form验证
  • 生成html标签(保留上次提交的内容)

详细:

1
2
3
4
5
6
7
8
class TestForm(forms.Form):
username = fields.CharField( # 静态字段
required=True,
min_length=6,
max_length=8,
error_messages={"required":"用户名不能为空", "min_length":"最少6位"},
widget = widgets.TextInput(attrs={'class': 'form-control'}) # 插件
)

基本使用

模块导入->类定义->定义字段-> 定义插件-> 实例化-> 传入前端->前端渲染

1
2
from django  import forms
from django.forms import fields,widgets

views.py定义Form类,写出来常用插件用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class TestForm(forms.Form):

n1 = fields.CharField(
widget = widgets.TextInput()
)

n2 = fields.CharField(
widget = widgets.PasswordInput()
)

n3 = fields.CharField(
widget=widgets.Textarea()
)

n4 = fields.CharField(
widget=widgets.Select(choices=[(1,"超级管理员"),(2,"普通用户")])
)

单选多选总结:
1 把上面CharField改为ChoiceField就好了,并choices=[]提到前面来
2 单选CharField就可以,多选一定记得用ChoicField,并且choices=[]提前

1
2
3
4
5
6
7
8
9
# n5 = fields.CharField(  
# # 这里是有问题的,CharField只能是字符串,"n5":[1,3]默认值是一个列表,后端没法接收数据。
# widget=widgets.SelectMultiple(choices=[(1,"北京"),(2,"上海"),(3,"成都")])
# )

n5 = fields.ChoiceField(
choices=[(1, "北京"), (2, "上海"), (3, "成都")],
widget=widgets.SelectMultiple()
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
n6 = fields.IntegerField(
widget=widgets.RadioSelect(choices=[(1,"超级管理员"),(2,"普通用户")])
)

n7 = fields.CharField( # 这里只会生成CheckboxInput标签 <input type="checkbox" name="n7" required="" id="id_n7">
widget=widgets.CheckboxInput()
)

n8 = fields.ChoiceField( # 真正生成checkbox组写法
choices=[(1, "北京"), (2, "上海"), (3, "成都")],
widget = widgets.CheckboxSelectMultiple()
)

n9 = fields.FileField(
widget=widgets.FileInput()
)

实例化Form类时传入默认值用于前端展示,主要学习文件上传的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def test(request):
if request.method == "GET":
obj = TestForm(
initial={"n1":"请输入","n2":"xxx","n3":"文本输入","n4":1,"n5":[1,3], "n6":2,"n7":"","n8":[2,3]}
)
return render(request, "test.html",{"obj":obj})

if request.method == "POST":
# 文件提交保存在request.FILES
# obj = TestForm(data=request.POST,files=request.FILES)
# if obj.is_valid():
# # obj.cleaned_data['n9'] 这是上传的文件对象
# #obj.cleaned_data['n9'].name 这是上传文件名
# files_obj = obj.cleaned_data['n9']
# f = open(files_obj.name, 'wb')
# for chunck in files_obj.chunks():
# f.write(chunck)
# f.close()
# else:
# pass
files_obj = request.FILES.get("n9")
f = open(files_obj.name, 'wb')
for chunck in files_obj.chunks():
f.write(chunck)
f.close()

return redirect('/test/')

提交文件需要enctype="multipart/form-data"
测试时忽略其它值用novalidate
test.html

1
2
3
4
5
6
7
8
9
10
11
12
13
<form action="/test/" method="post" enctype="multipart/form-data" novalidate>
{% csrf_token %}
{{ obj.n1 }}
{{ obj.n2 }}
{{ obj.n3 }}
{{ obj.n4 }}
{{ obj.n5 }}
{{ obj.n6 }}
{{ obj.n7 }}
{{ obj.n8 }}
{{ obj.n9 }}
<input type="submit" value="提交"/>
</form>

常用字段

1
2
3
4
5
6
CharField               字符串 
EmailField 字符串(邮箱格式)
IntegerField 字符串(整形格式)
GenericIPAddressField 字符串(Ip格式)
RegexField 字符串(正则自定义)
FileField 文件对象

常用插件

1
2
3
4
5
6
7
8
9
10
11
12
TextInput
PasswordInput
Textarea
FileInput()

Select(attrs={'class': 'form-control'},choices=[(1,"超级管理员"),(2,"普通用户")])
SelectMultiple(attrs={'class': 'form-control'}) # choices=[(1,"北京"),(2,"上海"),(3,"成都")]

RadioSelect(choices=[(1,"超级管理员"),(2,"普通用户")])

CheckboxInput()
CheckboxSelectMultiple()

Form问题

在前端使用选择标签渲染时,多表foreigh key跨表查询数据源无法实时更新。
比如choices的选项可以从数据库中获取,但是由于是静态字段获取的值无法实时更新,那么需要自定义构造方法从而达到此目的。

方法有很多,推荐

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator

class MyForm(Form):

user = fields.ChoiceField(
# choices=((1, '上海'), (2, '北京'),),
initial=2,
widget=widgets.Select
)

def __init__(self, *args, **kwargs):
super(MyForm,self).__init__(*args, **kwargs)
# self.fields['user'].widget.choices = ((1, '上海'), (2, '北京'),)
# 或
self.fields['user'].widget.choices = models.Classes.objects.all().value_list('id','caption')

总结

Django Form功能一是验证,功能二是用于生成html标签并且能保留上次提交的内容。
注意Form验证读取数据时的数据源实时更新问题,一般我们自定义Form类的构造方法实现。

还有很多要学习的。。。