Django Form组件实例:登录界面[Form表单提交,Ajax提交]
"""
本例中使用Form和Ajax进行了数据提交,Form提交有一个问题,就是输入错误的数据,刷新之后原有的数据会丢失。注意到Form组件可以生成HTML标签,将Form生成的对象传到前端,就可以保留
原有的内容,具体见下文:
"""
1 from django.shortcuts import * 2 from app02 import models 3 import json 4 5 # Create your views here. 6 def test(request): 7 wbq=models.userinfo.objects.filter(id=1).first() 8 print('***************',wbq.nickname) 9 related=wbq.girl.all() 10 11 for u in related: 12 print(u.g.username) 13 return HttpResponse('*****ok') 14 15 16 """ 17 中间件: 18 -类 19 process_request 20 process_response(...response) 21 必须要有返回值 22 return response 23 24 25 process_view 26 process_exception 27 process_template_view 28 29 -注册中间件 30 中间件从上到下执行,有先后顺序 31 32 33 -应用 34 对所有请求或一部分请求做批量处理 35 36 37 38 form验证:减轻数据库的压力,先对用户写的数据进行验证 39 40 -需要对请求数据做验证 41 -获取数据然后进行验证 42 43 本例要求: 44 用户名6~18位,必须为邮件格式 45 密码不能为空,必须包含下划线 数字 英文字母 ,长度5~18 46 问题-如果使用正则表达式,则会重复劳动 47 48 django中提供form组件 49 50 1.定义规则 51 from django.forms import Form 52 from django.forms import fields 53 a.class xxx(Form): 54 xxx=fields.CharField(required=TRUE,..........) 55 b.obj=LoginForm(用户提交的数据) 56 c. result=obj.is_valid() 57 d. obj.cleaned_data 58 e. obj.errors 59 60 61 有如下几种: 62 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 63 | t1 = fields.CharField | 64 | t2 = fields.IntegerField | 65 | t3 = fields.EmailField | 66 | t5=fields.SlugField() | 67 | t6=fields.GenericIPAddressField() | 68 | t7=fields.DateField() | 69 | t8=fields.DateTimeField() | 70 | t9=fields.RegexField('139\d+') #自定义正则表达式的字段验证规则 | 71 | | 72 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-| 73 74 Field 75 required=True, 是否允许为空 76 widget=None, HTML插件 77 label=None, 用于生成Label标签或显示内容 78 initial=None, 初始值 79 help_text='', 帮助信息(在标签旁边显示) 80 error_messages=None, 错误信息 {'required': '不能为空', 'invalid': '格式错误'} 81 show_hidden_initial=False, 是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直) 82 validators=[], 自定义验证规则 83 localize=False, 是否支持本地化 84 disabled=False, 是否可以编辑 85 label_suffix=None Label内容后缀 86 87 88 CharField(Field) 89 max_length=None, 最大长度 90 min_length=None, 最小长度 91 strip=True 是否移除用户输入空白 92 93 IntegerField(Field) 94 max_value=None, 最大值 95 min_value=None, 最小值 96 97 FloatField(IntegerField) 98 ... 99 100 DecimalField(IntegerField) 101 max_value=None, 最大值 102 min_value=None, 最小值 103 max_digits=None, 总长度 104 decimal_places=None, 小数位长度 105 106 BaseTemporalField(Field) 107 input_formats=None 时间格式化 108 109 DateField(BaseTemporalField) 格式:2015-09-01 110 TimeField(BaseTemporalField) 格式:11:12 111 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 112 113 DurationField(Field) 时间间隔:%d %H:%M:%S.%f 114 ... 115 116 RegexField(CharField) 117 regex, 自定制正则表达式 118 max_length=None, 最大长度 119 min_length=None, 最小长度 120 error_message=None, 忽略,错误信息使用 error_messages={'invalid': '...'} 121 122 EmailField(CharField) 123 ... 124 125 FileField(Field) 126 allow_empty_file=False 是否允许空文件 127 128 ImageField(FileField) 129 ... 130 注:需要PIL模块,pip3 install Pillow 131 以上两个字典使用时,需要注意两点: 132 - form表单中 enctype="multipart/form-data" 133 - view函数中 obj = MyForm(request.POST, request.FILES) 134 135 URLField(Field) 136 ... 137 138 139 BooleanField(Field) 140 ... 141 142 NullBooleanField(BooleanField) 143 ... 144 145 ChoiceField(Field) 146 ... 147 choices=(), 选项,如:choices = ((0,'上海'),(1,'北京'),) 148 required=True, 是否必填 149 widget=None, 插件,默认select插件 150 label=None, Label内容 151 initial=None, 初始值 152 help_text='', 帮助提示 153 154 155 ModelChoiceField(ChoiceField) 156 ... django.forms.models.ModelChoiceField 157 queryset, # 查询数据库中的数据 158 empty_label="---------", # 默认空显示内容 159 to_field_name=None, # HTML中value的值对应的字段 160 limit_choices_to=None # ModelForm中对queryset二次筛选 161 162 ModelMultipleChoiceField(ModelChoiceField) 163 ... django.forms.models.ModelMultipleChoiceField 164 165 166 167 TypedChoiceField(ChoiceField) 168 coerce = lambda val: val 对选中的值进行一次转换 169 empty_value= '' 空值的默认值 170 171 MultipleChoiceField(ChoiceField) 172 ... 173 174 TypedMultipleChoiceField(MultipleChoiceField) 175 coerce = lambda val: val 对选中的每一个值进行一次转换 176 empty_value= '' 空值的默认值 177 178 ComboField(Field) 179 fields=() 使用多个验证,如下:即验证最大长度20,又验证邮箱格式 180 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),]) 181 182 MultiValueField(Field) 183 PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用 184 185 SplitDateTimeField(MultiValueField) 186 input_date_formats=None, 格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y'] 187 input_time_formats=None 格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'] 188 189 FilePathField(ChoiceField) 文件选项,目录下文件显示在页面中 190 path, 文件夹路径 191 match=None, 正则匹配 192 recursive=False, 递归下面的文件夹 193 allow_files=True, 允许文件 194 allow_folders=False, 允许文件夹 195 required=True, 196 widget=None, 197 label=None, 198 initial=None, 199 help_text='' 200 201 GenericIPAddressField 202 protocol='both', both,ipv4,ipv6支持的IP格式 203 unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用 204 205 SlugField(CharField) 数字,字母,下划线,减号(连字符) 206 ... 207 208 UUIDField(CharField) uuid类型 209 ... 210 211 """ 212 from django.forms import * 213 class LoginForm(Form): 214 username=fields.CharField( 215 label='用户名', 216 max_length=6, 217 min_length=3, 218 required=True, 219 error_messages={'required':'用户名不能为空', 220 'min_length':'太短了', 221 'max_length':'太长了'} 222 )#required:不能为空 223 224 password=fields.CharField( 225 max_length=6, 226 required=True, 227 error_messages={ 228 'required':'还没写', 229 'max_length':'太大了', 230 231 'invalid':'格式错了', 232 233 } 234 ) 235 236 237 238 email=fields.EmailField(required=True, 239 error_messages={'required':'还没写'} 240 241 ) 242 """ 243 生成HTML标签: 244 widget=widgets.Select, ******** 用于指定生成怎样的HTML,select,textarea,input/. 245 label='用户名', # obj.t1.label 246 disabled=False, # 是否可以编辑 247 label_suffix='--->', # Label内容后缀 需要在html模版中添加{{ obj.as_p }}来显示出所有Form类中定义的字段 248 initial='666', # 无用,猜测有问题,应该在input框中显示默认值 249 help_text='。。。。。。', # 提供帮助信息 250 251 252 """ 253 254 255 256 257 def login1(request): 258 obj=LoginForm() 259 #生成HTML标签 obj.username=<input type='text' name='username' values='xxx'> 260 261 ret={'status':True,'msg':None} 262 263 264 if request.method == 'GET': 265 return render(request, 'login1.html',{'obj':obj}) 266 else: 267 obj=LoginForm(request.POST) 268 # ret=obj.is_valid() 269 # print(ret) 270 print(obj.is_valid()) 271 272 273 if obj.is_valid(): 274 #格式正确 275 print(obj.cleaned_data)#字典类型,数据库里直接写create(**dict) 276 277 else: 278 print(obj.errors) 279 #格式错误 280 # print(obj.errors) 281 # print(json.dumps(obj.errors)) 282 # ret['status'] = False 283 # ret['msg'] = obj.errors 284 # v=json.dumps(ret) 285 # # return HttpResponse(v) 286 return render(request,'login1.html',{'obj':obj}) 287 288 # return HttpResponse('000') 289 290 291 292 293 294 """ 295 errors 对象 296 username Ensure this value has at least 6 characters (it has 1). 297 password Ensure this value has at most 16 characters (it has 18). 298 """ 299 300 """ 301 常规写法 302 303 304 else: 305 username=request.POST.get('username') 306 password=request.POST.get('password') 307 if username=='alex' and password=='123': 308 return redirect('http://www.baidu.com') 309 else:return render(request,'login1.html',{'error':'用户名或密码错误'}) 310 311 312 :param request: 313 :return: 314 """
HTML部分:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <form id="f1" method="post" action="/login1.html" novalidate> 9 {% csrf_token %} 10 <p>用户名{{ obj.username }}{{ obj.errors.username.0 }}</p> 11 <p>密码{{ obj.password }}{{ obj.errors.password.0 }}</p> 12 <p>邮箱{{ obj.email }}{{ obj.errors.email.0 }}</p> 13 {# <p>用户名<input type="text" name="username" placeholder="enter your username">{{ obj.errors.username.0 }}</p>#} 14 {# <p>密码<input type="password" name="password" placeholder="enter your password">{{ obj.errors.password.0 }}</p>#} 15 <input type="submit" value="submit">提交 //ajax 提交,给提交俩字绑定事件 <a onclick='sub()'>提交</a> 16 </form> 17 18 <script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script> 19 <script> 20 21 function sub() { 22 $('.c1').remove(); 23 $.ajax( 24 25 { 26 url:'/login1.html', 27 type:'POST', 28 data:$('#f1').serialize(),//user=alex&password=123 29 dataType:'JSON', 30 success :function (arg) { 31 //console.log(arg); 32 if(arg['status']) { 33 34 }else { 35 $.each(arg.msg,function (index,value) {//对msg中的元素进行循环 36 //msg 格式: username: 用户名不能为空 37 console.log(index,value);//key:username/password行名 value :错误信息, 38 var tag=document.createElement('span'); 39 tag.innerHTML=value[0]; 40 tag.className='c1'; 41 $('#f1').find('input[name="'+index+'"]').after(tag);//查找input name=password password就是index,也就是KEY 42 })//after:把tag加到后面去 43 44 45 } 46 47 48 49 } 50 51 52 } 53 ) 54 55 } 56 57 58 59 60 </script> 61 62 </body> 63 </html>