一 建立一个form组件css
导入forms模块组件:from django import formshtml
建立组件:建立一个类继承者forms.Form这个类git
类型:正则表达式
CharField:字符串类型,min_length:字符长度不能小于多少;max_length:字符的长度不能大于多少,error_messages:能够根据保存信息显示对应的中文报错,required:该字段不可以为空,widget:对input标签操做。数据库
IntegerField:整数类型,invalid:格式错误django
MultiplechioceField:设置字段为多选框(单选框)。initial=[数字,]:初始个数。choices=((value,数据),(value,数据)):为多选框(单选框赋值)。widgets.CheckboxSelectMultiple:设置为复选框bootstrap
其余类型:app
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类型 ...
根据不一样要求为表单加上不一样的属性值:导入from django.forms impost widgetside
widgets.PasswoedInput:加上密文的属性值,addrs:为指定的标签加上属性。函数
widgets.TextInput:文本信息
widgets.Select:下拉菜单,choices:为option出入值和value属性值
钩子clean:首先导入异常:from django.core.exceptions import ValidationError。
局部钩子:clean_字段名,就是使用clean_加上一个字段名。用于字段校验
raise calidationsError:抛出错误信息
cleaned_data:若是符合条件,数据就会存放在这里面,可使用get获取是一个有序的字典格式,从上往下依次判断添加。
for name, field in self.fields.items(): try: value = field.clean(value) self.cleaned_data[name] = value if hasattr(self, 'clean_%s' % name): value = getattr(self, 'clean_%s' % name)() self.cleaned_data[name] = value except ValidationError as e: self.add_error(name, e)
全局钩子:clean,直接在这个函数里面定义功能,能够用于多个字段的操做和比较,直接能够获取cleaned_data里面的数据。
__all__:全局抛出来的错误存放在这个里面的。
self.clean() # def self.clean():return self.cleaned_data return not self.errors # True或者False
from django import forms from django.forms import widgets from django.core.exceptions import ValidationError class LoginForm(forms.Form): user=forms.CharField(min_length=5,max_length=12, error_messages={ "required":"该字段不能为空", "min_length":"该字段的长度不能小于5", "max_length":"该字段的长度不能大于12"}, widget=widgets.TextInput(attrs={"class":"form-control"}) ) pwd=forms.CharField( error_messages={ "invalid": "必须是数字" }, widget=widgets.PasswordInput(attrs={"class":"form-control",}) ) gender=forms.CharField( widget=widgets.Select(choices=((1,'男'),(0,'女'),)) ) usersss = forms.MultipleChoiceField( initial=[2, ], choices=((1, '上海'), (2, '北京'),), widget=widgets.CheckboxSelectMultiple ) def clean_user(self): print("============",self.cleaned_data.get("pwd")) # ============ None if not self.cleaned_data.get("user").isdigit(): return self.cleaned_data.get("user") else: raise ValidationError("该字段不能是纯数字") def clean_pwd(self): print("-----------------",self.cleaned_data.get("user")) import re val=self.cleaned_data.get("pwd") ret=re.findall("^\d{6}yuan$",val) if ret: return val else: raise ValidationError("密码不符合设定要求") def clean(self): if self.cleaned_data.get("user") and self.cleaned_data.get("pwd"): if self.cleaned_data.get("user") != self.cleaned_data.get("pwd"): return self.cleaned_data else: raise ValidationError("用户名与密码不能一致!") return self.cleaned_data
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
经常使用选择插件:
# 单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 # )
二 实例form对象
实例化时: self.fields={ "username":"字段规则对象", "password":"字段规则对象", }
LoginForm:form自建实例的对象存放的地点,request.POST:将数据传递给对应的字段,绑定数据的表单实例
is_valid:校验,将检验是否符合要求,返回的是一个布尔值
cleaned_data:检验正确数据就存放在这里面,是以字典的格式存放的,出数据。
errors:检验没有经过或错误的信息存放在这个里面,是以字典的格式存放的。errors.get获取里面的某些数据。
from django.shortcuts import render,HttpResponse # Create your views here. from django import forms from .models import * from django.forms import widgets from .forms import * def login(request): if request.method=="POST": #print(request.POST) #<QueryDict: {'csrfmiddlewaretoken': ['0xrifjX7jplIZwngbrRjpHPXw6kyDVa2Erca0sGYfjH9UuDfHzNUdMzlh7EH2v44'], 'user': ['asdas'], 'pwd': ['12321321']}> login_form=LoginForm(request.POST) # 将数据传给对应字段 绑定数据的表单实例 ''' # self.cleaned_data={"pwd":"12312412"} # self.errors={"user":"yuan",} ''' if login_form.is_valid(): print("经过验证") print(login_form.cleaned_data) print("use:",login_form.cleaned_data.get("user")) print(login_form.errors) ############### # user=login_form.cleaned_data.get("user") # pwd=login_form.cleaned_data.get("pwd") # UserInfo.objects.filter(username=user,password=pwd) # UserInfo.objects.filter(**login_form.cleaned_data) return HttpResponse("OK") else: # print("验证失败") # print(login_form.cleaned_data) # {'pwd': 77777} # print(login_form.errors) # ################## login_form.errors是什么类型 # print(type(login_form.errors))# <class 'django.forms.utils.ErrorDict'> # ###################获取login_form.errors的某个键的值 # print(login_form.errors.get("user")) # print(type(login_form.errors.get("pwd")))# <class 'django.forms.utils.ErrorList'> # # #login_form.errors={"user":["小于5位","不是数字"],"pwd":["",""]} errors=login_form.errors# {"user":["该字段不能是纯数字",],"pwd":["",""]} print("errors-->",errors) error_all=errors.get("__all__") return render(request, "login.html", {"login_form": login_form,"errors":errors,"error_all":error_all}) #### get请求 login_form=LoginForm() # form组件的实例对象 未绑定表单实例 return render(request,"login.html",{"login_form":login_form})
三 html文件渲染
模板导入input标签:直接用对象.字段取出内容 {{ 对象.字段}}
模板导入错误信息:直接使用srrors.字段名.0取出数据{{ srrors.字段名.0 }}
form组件只可以直接渲染input标签,form标签仍是须要本身写的。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css"> <style> .container{ margin-top: 100px; } </style> </head> <body> <div class="container"> <div class="row"> <div class="col-md-6"> <form action="/login/" method="post"> {% csrf_token %} <div class="form-group"> <label for="user">user</label> {{ login_form.user }} <span>{{ errors.user.0 }}</span> </div> <div class="form-group"> <label for="pwd">pwd</label> {{ login_form.pwd }} <span>{{ errors.pwd.0 }}</span> </div> <div class="form-group"> <label for="gender">gender</label> {{ login_form.gender }}<span>{{ error_all.0 }}</span> </div> <p>{{ login_form.usersss }}</p> <button type="submit" class="btn btn-default">Submit</button> </form> <hr> {# <form action="">#} {# {{ login_form.as_p }}#} {# </form>#} </div> </div> </div> </body> </html>
四 其余渲染对象
对于<label>/<input>
对,还有几个输出选项:
{{ form.as_table }}
以表格的形式将它们渲染在<tr>
标签中{{ form.as_p }}
将它们渲染在<p>
标签中{{ form.as_ul }}
将它们渲染在<li>
标签中注意,你必须本身提供<table>
或<ul>
元素。
{{ form.as_p }}
结果以下:
<form action=""> <p> <label for="id_username">Username:</label> <input id="id_username" maxlength="100" name="username" type="text" required=""> </p> <p> <label for="id_password">Password:</label> <input id="id_password" maxlength="100" name="password" placeholder="password" type="password" required=""> </p> <p> <label for="id_telephone">Telephone:</label> <input id="id_telephone" name="telephone" type="number" required=""> </p> <p> <label for="id_email">Email:</label> <input id="id_email" name="email" type="email" required=""> </p> <p> <label for="id_is_married">Is married:</label> <input id="id_is_married" name="is_married" type="checkbox"> </p> <input type="submit" value="注册"> </form>
这种渲染有了限制,不能个自定义的渲染,而是将全部的字段所有渲染过去。
手动渲染:咱们没有必要非要让Django 来分拆表单的字段;若是咱们喜欢,咱们能够手工来作每一个字段都是表单的一个属性,可使用{{ form.name_of_field }}
访问,并将在Django 模板中正确地渲染
<div class="fieldWrapper"> {{ form.Username.errors }} {{ form.Username.label_tag }} {{ form.Username }} </div>
五 表单渲染的错误信息
registerForm=RegisterForm(request.POST) print(type(registerForm.errors)) #<class 'django.forms.utils.ErrorDict'> print(type(registerForm.errors["username"])) #<class 'django.forms.utils.ErrorList'>
使用{{ form.name_of_field.errors }} 显示表单错误的一个清单,并渲染成一个ul。看上去可能像: <ul class="errorlist"> <li>Sender is required.</li> </ul>
补充练习:
from django.shortcuts import render # Create your views here. from .models import UserInfor from django.forms import ModelForm from django import forms from .models import * print(City.objects.all().values_list("id","name")) # class RegForm(forms.Form): # user = forms.CharField(max_length=32) # #gender_tuple=(0,'上海'),(1,'北京'),(2,'保定') # gender = forms.ChoiceField(choices =City.objects.all().values_list("id","name")) # # def __init__(self,*args,**kwargs): # super(RegForm,self).__init__(*args,**kwargs) # #print("Ok") # print(self.fields["gender"].choices) # self.fields["gender"].choices=City.objects.all().values_list("id","name") ''' class UserInfor(models.Model): user=models.CharField(max_length=32) gender=models.IntegerField(choices=((1,"男"),(2,"女"))) city=models.ForeignKey("City",default=1) roles=models.ManyToManyField("Roles",default=1) ||||| class UserInfor(forms.Form): user=forms.CharField() gender=forms.TypedChoiceField(choices=((1,"男"),(2,"女"))) city=forms.ModelChoiceField(choices=City.objects.all()) roles=forms.ModelMultipleChoiceField(choices=Roles.objects.all()) ''' class RegForm(ModelForm): class Meta: model=UserInfor fields="__all__" def reg(reqeust): form=RegForm() print(form.fields) return render(reqeust,"reg.html",{"form":form})