Django框架之Form组件
新手上路
From组件的主要功能:
- 1,对form表单提交的数据进行校验。
- 内部基于正则进行匹配
- 2,from表单提交保存上次提交的数据。
- 生成HTML标签
初入大荒
1,创建Form类
class StudentForm(Form): #字段名,最好跟数据库内的字段名一样,好操作 #如CharField,内部包含了正则表达式, name = fields.CharField(max_length=12, min_length=2, required=True, widget=widgets.TextInput(attrs={"class":"form-control"}),#添加css样式,标签的class名 error_messages={ "max_length":"名字太长了", #错误提示信息 "min_length":"名字太短了", "required":"名字不能为空", }) email = fields.EmailField(widget=widgets.TextInput(attrs={"class":"form-control"})) age = fields.IntegerField(min_value=10, max_value=30, widget=widgets.TextInput(attrs={"class":"form-control"}) ) cls_id = fields.IntegerField( widget=widgets.Select(choices=models.Classes.objects.values_list("id","title"), attrs={"class":"form-control"}) )
2,Form类对应函数
def add_student(request): if request.method == "GET": obj = StudentForm() #实例化对象,在HTML生成input标签 #print(obj) return render(request,"add_student.html",{"obj":obj}) else: obj = StudentForm(request.POST) # request.POST 内包含里提交的所有信息, print(obj) if obj.is_valid(): #返回值只有True或False models.Student.objects.create(**obj.cleaned_data) #向数据库中添加数据 #print(obj.cleaned_data) #这里是提交的所有数据,字典格式,经过内部正则匹配成功的 return redirect("/student/") print(obj.errors) #正则匹配失败的,错误的所有信息 return render(request, "add_student.html", {"obj": obj})
3,生成HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css"> </head> <body> <h1 style="width: 200px;height: 100px;margin: 0 auto">添加学生</h1> <div style="width: 500px;margin: 0 auto;"> <form class="form-horizontal" action="/add_student/" method="POST" novalidate> {% csrf_token %} <div class="form-group"> <label class="col-sm-2 control-label">姓名:</label> <div class="col-sm-10"> {{ obj.name }}{{ obj.errors.name.0 }} </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">邮箱:</label> <div class="col-sm-10"> {{ obj.email }}{{ obj.errors.email.0 }} </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">年龄:</label> <div class="col-sm-10"> {{ obj.age }}{{ obj.errors.age.0 }} </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">班级:</label> <div class="col-sm-10"> {{ obj.cls_id }}{{ obj.errors.cls_id.0 }} </div> </div> <div class="form-group"> <label class="col-sm-2 control-label"></label> <div class="col-sm-10"> <input type="submit" value="提交"> </div> </div> </form> </div> </body> </html>
崭露头角
创建Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML;
1、Django中Form类内置字段如下:
- 常用字段
'''
常用字段
CharField 字符串类型
ChoiceField *****
MultipleChoiceField
IntegerField #整数类型
DateField
DateTimeField #时间类型
EmailField #邮件类型
FileField #文件类型
RegexField #再次正则匹配
title = fields.RegexField("鸡蛋\w+")
'''
- 详细字段
“”“ Field required=True, 是否允许为空 widget=None, HTML插件 label=None, 用于生成Label标签或显示内容 initial=None, 初始值 help_text='', 帮助信息(在标签旁边显示) error_messages=None, 错误信息 {'required': '不能为空', 'invalid': '格式错误'} show_hidden_initial=False, 是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直) validators=[], 自定义验证规则 localize=False, 是否支持本地化 disabled=False, 是否可以编辑 label_suffix=None Label内容后缀 CharField(Field) max_length=None, 最大长度 min_length=None, 最小长度 strip=True 是否移除用户输入空白 IntegerField(Field) max_value=None, 最大值 min_value=None, 最小值 FloatField(IntegerField) ... DecimalField(IntegerField) max_value=None, 最大值 min_value=None, 最小值 max_digits=None, 总长度 decimal_places=None, 小数位长度 BaseTemporalField(Field) input_formats=None 时间格式化 DateField(BaseTemporalField) 格式:2015-09-01 TimeField(BaseTemporalField) 格式:11:12 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 DurationField(Field) 时间间隔:%d %H:%M:%S.%f ... RegexField(CharField) regex, 自定制正则表达式 max_length=None, 最大长度 min_length=None, 最小长度 error_message=None, 忽略,错误信息使用 error_messages={'invalid': '...'} EmailField(CharField) ... FileField(Field) allow_empty_file=False 是否允许空文件 ImageField(FileField) ... 注:需要PIL模块,pip3 install Pillow 以上两个字典使用时,需要注意两点: - form表单中 enctype="multipart/form-data" - view函数中 obj = MyForm(request.POST, request.FILES) URLField(Field) ... BooleanField(Field) ... NullBooleanField(BooleanField) ... ChoiceField(Field) ... choices=(), 选项,如:choices = ((0,'上海'),(1,'北京'),) required=True, 是否必填 widget=None, 插件,默认select插件 label=None, Label内容 initial=None, 初始值 help_text='', 帮助提示 ModelChoiceField(ChoiceField) ... django.forms.models.ModelChoiceField queryset, # 查询数据库中的数据 empty_label="---------", # 默认空显示内容 to_field_name=None, # HTML中value的值对应的字段 limit_choices_to=None # ModelForm中对queryset二次筛选 ModelMultipleChoiceField(ModelChoiceField) ... django.forms.models.ModelMultipleChoiceField TypedChoiceField(ChoiceField) coerce = lambda val: val 对选中的值进行一次转换 empty_value= '' 空值的默认值 MultipleChoiceField(ChoiceField) ... TypedMultipleChoiceField(MultipleChoiceField) coerce = lambda val: val 对选中的每一个值进行一次转换 empty_value= '' 空值的默认值 ComboField(Field) fields=() 使用多个验证,如下:即验证最大长度20,又验证邮箱格式 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),]) MultiValueField(Field) PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用 SplitDateTimeField(MultiValueField) input_date_formats=None, 格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y'] input_time_formats=None 格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'] FilePathField(ChoiceField) 文件选项,目录下文件显示在页面中 path, 文件夹路径 match=None, 正则匹配 recursive=False, 递归下面的文件夹 allow_files=True, 允许文件 allow_folders=False, 允许文件夹 required=True, widget=None, label=None, initial=None, help_text='' GenericIPAddressField protocol='both', both,ipv4,ipv6支持的IP格式 unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用 SlugField(CharField) 数字,字母,下划线,减号(连字符) ... UUIDField(CharField) uuid类型 ... ”“”
2,Dhango中的Form类插件
- 常用插件
复制代码 class TestForm(Form): t1 = fields.CharField( widget=widgets.Textarea() #生成文本框标签 ) #单选 t2 = fields.CharField( widget=widgets.CheckboxInput ) #多选 t3 = fields.MultipleChoiceField(#生成多个checkbox标签 choices=[(1,"篮球"),(2,"足球"),(3,"乒乓球")], widget=widgets.CheckboxSelectMultiple ) #radio属性时互斥的,只能选择一个 t4 = fields.ChoiceField( choices=[(1, "篮球"), (2, "足球"), (3,"乒乓球"),(4,"橄榄球")], widget=widgets.RadioSelect ) t5 = fields.FileField( #文件对象,针对文件类型的 widget=widgets.FileInput )
- 内置插件
TextInput(Input)
NumberInput(TextInput)
EmailInput(TextInput)
URLInput(TextInput)
PasswordInput(TextInput)
HiddenInput(TextInput)
Textarea(Widget)
DateInput(DateTimeBaseInput)
DateTimeInput(DateTimeBaseInput)
TimeInput(DateTimeBaseInput)
CheckboxInput
Select
NullBooleanSelect
SelectMultiple
RadioSelect
CheckboxSelectMultiple
FileInput
ClearableFileInput
MultipleHiddenInput
SplitDateTimeWidget
SplitHiddenDateTimeWidget
SelectDateWidget
3,页面展示
# 灵活用法,生成单个标签 <form> {{obj.xx}} {{obj.xx}} {{obj.xx}} {{obj.xx}} </form>
# 简单用法,局限性大,生成多个标签, #生成多个P标签 {{obj.as_p}} #生成li标签,需要在HTML创建好ul标签,只能生成li标签 <ul> {{obj.as_ul}} </ul> #生成table标签,需要在HTML创建好table标签,只能生成tr,td标签 <table> {{obj.as_table}} </table>
锋芒毕露
单选或者多选时、数据源是否可以实时更新、、、
在使用选择标签时,需要注意choices的选项可以从数据库中获取,但是由于是静态字段 (获取的值无法实时更新),需要我们自定义方法来实现,
方法一:推荐用
class TeacherForm(Form):
name = fields.CharField(max_length=12,min_length=2)
email = fields.EmailField()
age = fields.IntegerField(max_value=60,min_value=20)
xx = fields.MultipleChoiceField(
#choices=models.Classes.objects.values_list("id","title"),
widget= widgets.SelectMultiple
)
def __init__(self,*args,**kwargs):
'''动态查询数据库信息'''
super(TeacherForm, self).__init__(*args,**kwargs)
self.fields["xx"].choices = models.Classes.objects.values_list("id","title")
方法二:
使用django提供的ModelChoiceField和ModelMultipleChoiceField字段来实现,用的方面少
from django.forms import models as form_model
class TeacherForm(Form):
name = fields.CharField(min_length=2)
xx = form_model.ModelMultipleChoiceField(queryset=models.Classes.objects.all())
名扬万里
上传文件:
- 方式一:
#方式一
def f1(request):
if request.method == "GET":
return render(request,"f1.html")
else:
file_obj = request.FILES.get("file")
f = open(os.path.join("static/images/",file_obj.name),"wb")
print(file_obj.chunks()) #内容对象
for chunk in file_obj.chunks():
f.write(chunk)
#print(chunk)
f.close()
return redirect("/f1/")
方式二:form组件
#form类
class FilesForm(Form):
user = fields.CharField()
files = fields.FileField()
def f2(request):
if request.method == "GET":
obj = FilesForm()
return render(request,"f2.html",{"obj":obj})
else:
obj = FilesForm(data=request.POST,files=request.FILES)
if obj.is_valid():
print(obj.cleaned_data)
print(obj.cleaned_data.get("files").name)
fiel_name = obj.cleaned_data.get("files").name
fiel = obj.cleaned_data.get("files")
print(obj.cleaned_data.get("files").size)
f = open(os.path.join("static",fiel_name),"wb")
for chunk in fiel:
f.write(chunk)
f.close()
return render(request,"f2.html",{"obj":obj})
震古烁今
Django的Form组件提供验证用户提交的数据并可以显示错误信息(或自定制),可以生成相应的Html代码。仅仅根据Form组件的验证或许满足不了一些需求,于是我们再Form的验证功能添加更多的验证功能,Form组件中留下了几个方便我们扩展方法。
日后再说。。。。。。。。。。。。。