Python 学习第二十三天 django Form知识
一,django 的form知识
1,利用views.py生成form表单
(1)views.py from表单代码
from django import forms from django.forms import widgets from django.forms import fields class FM(forms.Form): # 字段本身只做验证 user = fields.CharField( error_messages={'required': '用户名不能为空.'}, #required 为错误时提示的内容 widget=widgets.Textarea(attrs={'class': 'c1'}), label="用户名", ) pwd = fields.CharField( max_length=12, min_length=6, error_messages={'required': '密码不能为空.', 'min_length': '密码长度不能小于6', "max_length": '密码长度不能大于12'}, widget=widgets.PasswordInput(attrs={'class': 'c2'}) ) email = fields.EmailField(error_messages={'required': '邮箱不能为空.','invalid':"邮箱格式错误"})
(2)templates代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/fm/" method="POST"> {% csrf_token %} <p>{{ obj.user }} {{ obj.errors.user.0 }}</p> #已字典的形式,获取后端返回的obj对象,并通过obj.user 生成input标签 <p>{{ obj.pwd }} {{ obj.errors.pwd.0 }}</p> #obj.error为后端返回的一个ErrorDict,通过.user获取user标签的错误信息标签,在加.0获取错误信息的内容 <p>{{ obj.email }}{{ obj.errors.email.0 }}</p> <input type="submit" value="提交" /> </form> </body> </html>
(3)views.py 主函数代码
from app01 import models def fm(request): if request.method == "GET": obj = FM() #生成FM的对象,用户已get方法请求时,将obj对象返回到html页面 return render(request,'fm.html',{'obj': obj}) elif request.method == "POST": obj = FM(request.POST) r1 = obj.is_valid() if r1: #print(obj.cleaned_data) #如果输入的值正确,用户输入的内容将以字典的当时提交给后台 models.UserInfo.objects.create(**obj.cleaned_data) #后台获取数据后,可以直接写入数据库 else: return render(request,'fm.html', {'obj': obj})
2,生成其它html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/fm/" method="POST"> {% csrf_token %} {{ obj.as_p }} #生成p标签包裹的input标签 {{ obj.as_ul }} #生成ul标签包裹的input标签 <tables> {{ obj.as_tables}} #生成tables标签包裹的input标签 </tables> <input type="submit" value="提交" /> </form> </body> </html>
3,自定义生成的标签类型以及样式
django中自动生成form标签,是利用了django内置的forms类的一个widgets 方法,自定义生成form标签类型方法如下
from django.forms import widgets class FM(forms.Form): # 字段本身只做验证 user = fields.CharField( error_messages={'required': '用户名不能为空.'},
widget=widgets.Textarea #定义标签的类型为Textarea widget=widgets.Textarea(attrs={'class': 'c1'}), #这里定义widget插件的类型为Textarea,并且为这个Textarea添加一个c1样式,也可以以key-value的形式添加自定义样式 label="用户名", )
4,Form类,创建form类时会定义一些字段和插件,字段用来做数据验证,插件用来生成html
(1)django的内置字段
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)django内置插件
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
5,生成choice下拉框
from django import forms from django.forms import widgets from django.forms import fields class FM(forms.Form): city1 = fields.ChoiceField( choices=[(0,'上海'),(1,'广州'),(2,'东莞')] #生成单选的choice ) city2 = fields.MultipleChoiceField( choices=[(0,'上海'),(1,'广州'),(2,'东莞')] #生成多选的choice #html代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/fm/" method="POST"> {% csrf_token %} {{ obj.city1 }} {{ obj.city2 }} <input type="submit" value="提交" /> </form> </body> </html>
6,常用插件使用
# 单radio,值为字符串 # user = fields.CharField( # initial=2, # widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),)) # ) # 单radio,值为字符串 # user = fields.ChoiceField( # choices=((1, '上海'), (2, '北京'),), # initial=2, # widget=widgets.RadioSelect # ) # 单select,值为字符串 # user = fields.CharField( # initial=2, # widget=widgets.Select(choices=((1,'上海'),(2,'北京'),)) # ) # 单select,值为字符串 # user = fields.ChoiceField( # choices=((1, '上海'), (2, '北京'),), # initial=2, # widget=widgets.Select # ) # 多选select,值为列表 # user = fields.MultipleChoiceField( # choices=((1,'上海'),(2,'北京'),), # initial=[1,], # widget=widgets.SelectMultiple # ) # 单checkbox # user = fields.CharField( # widget=widgets.CheckboxInput() # ) # 多选checkbox,值为列表 # user = fields.MultipleChoiceField( # initial=[2, ], # choices=((1, '上海'), (2, '北京'),), # widget=widgets.CheckboxSelectMultiple # )
7,生成html页面的默认值
from app01 import models def fm(request): if request.method == "GET": dic = { # 从数据库中把数据获取到,并生成一个字典 "user": 'r1', 'pwd': '123123', 'email': 'sdfsd', 'city1': 1, 'city2': [1,2] } obj = FM(initial=dic) #将字典传给FM类 return render(request,'fm.html',{'obj': obj})