Django-form表单
---恢复内容开始---
Django-form表单
知识预览
- 构建一个表单
- 在Django 中构建一个表单
- Django Form 类详解
- 使用表单模板
-
构建一个表单
假设你想在你的网站上创建一个简单的表单,以获得用户的名字。你需要类似这样的模板:
12345<formaction="/your-name/"method="post"><labelfor="your_name">Yourname: </label><input id="your_name"type="text"name="your_name"><input type="submit"value="OK"></form>这是一个非常简单的表单。实际应用中,一个表单可能包含几十上百个字段,其中大部分需要预填充,而且我们预料到用户将来回编辑-提交几次才能完成操作。
我们可能需要在表单提交之前,在浏览器端作一些验证。我们可能想使用非常复杂的字段,以允许用户做类似从日历中挑选日期这样的事情,等等。
这个时候,让Django 来为我们完成大部分工作是很容易的。
so,两个突出优点:
1 form表单提交时,数据出现错误,返回的页面中仍可以保留之前输入的数据。
2 方便地限制字段条件
-
Django 中构建一个表单
Form 类
我们已经计划好了我们的 HTML 表单应该呈现的样子。在Django 中,我们的起始点是这里:
123456#forms.pyfromdjango import formsclass NameForm(forms.Form):your_name = forms.CharField(label='Your name', max_length=100)它定义一个
Form类,只带有一个字段(your_name)。字段允许的最大长度通过
max_length定义。它完成两件事情。首先,它在HTML 的<input>上放置一个maxlength="100"(这样浏览器将在第一时间阻止用户输入多于这个数目的字符)。它还意味着当Django 收到浏览器发送过来的表单时,它将验证数据的长度。Form的实例具有一个is_valid()方法,它为所有的字段运行验证的程序。当调用这个方法时,如果所有的字段都包含合法的数据,它将:- 返回
True - 将表单的数据放到
cleaned_data属性中。
完整的表单,第一次渲染时,看上去将像:
12<labelfor="your_name">Yourname: </label><input id="your_name"type="text"name="your_name"maxlength="100">注意它不包含
<form>标签和提交按钮。我们必须自己在模板中提供它们。视图
发送给Django 网站的表单数据通过一个视图处理,一般和发布这个表单的是同一个视图。这允许我们重用一些相同的逻辑。
当处理表单时,我们需要在视图中实例化它:
- 返回
-
from django.shortcuts import render from django.http import HttpResponseRedirect from .forms import NameForm def get_name(request): # if this is a POST request we need to process the form data if request.method == 'POST': # create a form instance and populate it with data from the request: form = NameForm(request.POST) # check whether it's valid: if form.is_valid(): # process the data in form.cleaned_data as required # ... # redirect to a new URL: return HttpResponseRedirect('/thanks/') # if a GET (or any other method) we'll create a blank form else: form = NameForm() return render(request, 'name.html', {'form': form}) 复制代码
如果访问视图的是一个
GET请求,它将创建一个空的表单实例并将它放置到要渲染的模板的上下文中。这是我们在第一个访问该URL 时预期发生的情况。如果表单的提交使用
POST请求,那么视图将再次创建一个表单实例并使用请求中的数据填充它:form = NameForm(request.POST)。这叫做”绑定数据至表单“(它现在是一个绑定的表单)。我们调用表单的
is_valid()方法;如果它不为True,我们将带着这个表单返回到模板。这时表单不再为空(未绑定),所以HTML 表单将用之前提交的数据填充,然后可以根据要求编辑并改正它。如果
is_valid()为True,我们将能够在cleaned_data属性中找到所有合法的表单数据。在发送HTTP 重定向给浏览器告诉它下一步的去向之前,我们可以用这个数据来更新数据库或者做其它处理。模板
我们不需要在name.html 模板中做很多工作。最简单的例子是:
12345<formaction="/your-name/"method="post">{% csrf_token %}{{ form }}<input type="submit"value="Submit"/></form>根据
{{ form }},所有的表单字段和它们的属性将通过Django 的模板语言拆分成HTML 标记 。注:Django 原生支持一个简单易用的跨站请求伪造的防护。当提交一个启用CSRF 防护的
POST表单时,你必须使用上面例子中的csrf_token模板标签。现在我们有了一个可以工作的网页表单,它通过Django Form 描述、通过视图处理并渲染成一个HTML
<form>。Django Form 类详解
绑定的和未绑定的表单实例
绑定的和未绑定的表单 之间的区别非常重要:
- 未绑定的表单没有关联的数据。当渲染给用户时,它将为空或包含默认的值。
- 绑定的表单具有提交的数据,因此可以用来检验数据是否合法。如果渲染一个不合法的绑定的表单,它将包含内联的错误信息,告诉用户如何纠正数据。
字段详解
考虑一个比上面的迷你示例更有用的一个表单,我们完成一个更加有用的注册表单:
-
#forms.py from django import forms class RegisterForm(forms.Form): username = forms.CharField(max_length=100, error_messages={"min_length":"最短为5个字符","required":"该字段不能为空"}, ) password = forms.CharField(max_length=100, widget=widgets.PasswordInput(attrs={"placeholder":"password"}) ) telephone=forms.IntegerField( error_messages={ "invalid":"格式错误" } ) gender=forms.CharField( initial=2, widget=widgets.Select(choices=((1,'上海'),(2,'北京'),)) ) email = forms.EmailField() is_married = forms.BooleanField(required=False)
Widgets
每个表单字段都有一个对应的
Widget类,它对应一个HTML 表单Widget,例如<input type="text">。在大部分情况下,字段都具有一个合理的默认Widget。例如,默认情况下,
CharField具有一个TextInput Widget,它在HTML 中生成一个<input type="text">。字段的数据
不管表单提交的是什么数据,一旦通过调用
is_valid()成功验证(is_valid()返回True),验证后的表单数据将位于form.cleaned_data字典中。这些数据已经为你转换好为Python 的类型。注:此时,你依然可以从
request.POST中直接访问到未验证的数据,但是访问验证后的数据更好一些。在上面的联系表单示例中,is_married将是一个布尔值。类似地,
IntegerField和FloatField字段分别将值转换为Python 的int和float。使用表单模板
你需要做的就是将表单实例放进模板的上下文。如果你的表单在
Context 中叫做form,那么{{ form }}将正确地渲染它的<label>和<input>元素。表单渲染的选项
对于
<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 模板中正确地渲染。例如:
|
1
2
3
4
5
|
<div class="fieldWrapper"> {{ form.Username.errors }} {{ form.Username.label_tag }} {{ form.Username }}</div> |
渲染表单的错误信息
1、
|
1
2
3
|
registerForm=RegisterForm(request.POST)print(type(registerForm.errors)) #<class 'django.forms.utils.ErrorDict'>print(type(registerForm.errors["username"])) #<class 'django.forms.utils.ErrorList'> |
2、
使用{{ form.name_of_field.errors }} 显示表单错误的一个清单,并渲染成一个ul。看上去可能像:
|
1
2
3
|
<ul class="errorlist"> <li>Sender is required.</li></ul> |
form组件的钩子
def foo(request):
if request.method=="POST":
regForm=RegForm(request.POST)
if regForm.is_valid():
pass
# 可用数据: regForm.cleaned_data,
# 将数据插入数据库表中
else:
pass
# 可用数据: regForm.errors
# 可以利用模板渲染讲errors嵌套到页面中返回
# 也可以打包到一个字典中,用于ajax返回
else:
regForm=RegForm()
return render(request,"register.html",{"regForm":regForm})
'''
实例化时:
self.fields={
"username":"字段规则对象",
"password":"字段规则对象",
}
is_valid时:
self._errors = {}
self.cleaned_data = {}
#局部钩子:
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)
# 全局钩子:
self.clean() # def self.clean():return self.cleaned_data
return not self.errors # True或者False
'''
form组件补充
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
3、常用选择插件:

# 单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表单中的request.POST


重要代码
from django.shortcuts import render,redirect,HttpResponse # Create your views here. from django import forms from django.forms import widgets #调用魔法标签,当定义属性时缺少要用的属性时用他来调出 class Loginform(forms.Form): #创建一个类,继承forms.Form的属性和方法 user=forms.CharField(max_length=12,min_length=5, error_messages={ #自定义错误信息 "required":'不能为空',# 为空时可以设置这个字段让他报这个错 'min_length':'最小度为5', #当小于最小字段是报这个错误 'max_length':'最大长度为12', 'invalid': '格式错误'}) pwd=forms.CharField(error_messages={},widget=widgets.PasswordInput()#缺少密码属性输入狂,可以用他来引入 ) def login(request): if request.method=='POST': print(request.POST) #他打印出的是提交的所有数据的字典<QueryDict: {'csrfmiddlewaretoken': # ['8VzVZ4ruXR25KeOaWg7TvSejIBaTh3G0xvGNrYK3DiQIoR8UB9Vyhymjl392JiFd'], # 'user': ['sdfsa'], 'pwd': ['aaa']}> form_obj=Loginform(request.POST) #将数据传入这个类 实例化 一个对象 if form_obj.is_valid():#检验成功 is_valid()是父类form 中的方法 #数据全部合格是走到这步 return HttpResponse('ok') else: #最少存在一个字段的错误,将页面返回,返回的页面包含刚刚填好的数据,不是空的数据,证明这个form_obj是上边的 print(form_obj.errors) print(type(form_obj.errors)) return render(request, 'login.html', {'form_obj': form_obj}) #返回一个带数据的表单,避免正确的数据还要重新填写 form_obj=Loginform() #这个是空的里边没有传值,与上边的不是一个实例化对象 return render(request,'login.html',{'form_obj':form_obj}) 返回一个空的表单页面
HTML中的写法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> {#<form action="" method="post">#} {# {% csrf_token %}#} {# {{ form_obj.as_p }}#} {# <input type="submit">#} {#</form>#} {#<hr>#} <form action="" method="post" novalidate> {# 要添加这条信息,否则浏览器会自动检测是否符合条件而不显示我写的内容#} {% csrf_token %} <label for="">用户名</label> {{ form_obj.user}} #取出用户名输入框 {# 用可能是多个错误信息,但是我只是取出错误信息列表中中的第一个错误信息 #} {# 取值等价于 form_obj.errors["user"][0] 母版语言,当取不到的时候不会报错,只是不渲染错误信息#} <span>{{ form_obj.errors.user.0 }}</span> <hr> <label for="">密码</label> {{ form_obj.pwd}} <span>{{ form_obj.errors.pwd.0 }}</span> <input type="submit"> </form> </body> </html>



is_valid时: self._errors = {} #这里存放的是错误信息 self.cleaned_data = {} #这里存放的是正确信息 #当 if form_obj.is_valid(): 成立时即是他为True时 即是所有的self._errors字典中的信息全为空, 才成能走这个成立是的内容 return HttpRespons('OK') 否则就走下边 else: return render(request,'login.html',{'form_obj': form_obj})
钩子

钩子定义顺序

当时当在 校验user的钩子中 想要取出还未校验的pwd字段时 是取不出来的

自定义钩子的代码
from django.shortcuts import render,redirect,HttpResponse from django.core.exceptions import NON_FIELD_ERRORS,ValidationError #引入这个模块,自定义钩子报错时,抛出这个错误 # Create your views here. from django import forms from django.forms import widgets #调用魔法标签,当定义属性时缺少要用的属性时用他来调出 class Loginform(forms.Form): user=forms.CharField(max_length=12,min_length=5, error_messages={ #自定义错误信息 "required":'不能为空',# 为空时可以设置这个字段让他报这个错 'min_length':'最小度为5', #当小于最小字段是报这个错误 'max_length':'最大长度为12', 'invalid': '格式错误'}) pwd=forms.CharField(error_messages={},widget=widgets.PasswordInput()#缺少密码属性输入狂,可以用他来引入 ) #钩子,校验字段 def clean_user(self):#校验那个字段就要clean_要校验的字段名 val=self.cleaned_data.get('user') if not val.isdigit(): #如果不全部是数字则通过校验 return val #通过校验将值返回给源码 else: raise ValidationError('用户名不能全为数字!') #当不符合是 抛出异常
def clean_pwd(self):#校验那个字段就要clean_要校验的字段名 val1=self.cleaned_data.get('user') #因为user已经执行完了,可以从这里取出user的值 不能在 user的钩子中取出 pwd 的值,因为他还没校验呢 val=self.cleaned_data.get('pwd') if val1==val: #如果用户名密码一致时,正常 return val #通过校验将值返回给源码 else: raise ValidationError('用户名密码不一样') #当不符合是 抛出异常

作业中的要注意的点
全局钩子的中的数据传入和取出
views 中的写法 这样将数据传送给模板
全局钩子中的数据不会管是否局部钩子执行和执行的效果(比如验证两次密码是否一致的全局钩子,
不会看局部钩字 密码是否全为数字 的执行效果)会直接执行

模板中这样接收数据

自定义一个form类和自己写钩子
from django.shortcuts import render,redirect,HttpResponse from django.core.exceptions import NON_FIELD_ERRORS,ValidationError #引入这个模块,自定义钩子报错时,抛出这个错误 # Create your views here. from django import forms from . import models from django.forms import widgets #调用魔法标签,当定义属性时缺少要用的属性时用他来调出 #实例化一个注册表单类 class Regform(forms.Form): user=forms.CharField(max_length=12,min_length=4, error_messages={'invalid':'格式错误', 'required':'不能为空', 'max_length':'不能超过12位', 'min_length':'不能小于4位' }) pwd=forms.CharField(widget=widgets.PasswordInput, error_messages={'invalid':'格式错误', 'required':'内容不能为空'}) pwd1=forms.CharField(widget=widgets.PasswordInput,) email=forms.EmailField(error_messages={'invalid':'格式错误', 'required':'内容不能为空'}) phone=forms.CharField(error_messages={ 'invalid':'格式错误', 'required':'内容不能为空' }) def clean_user(self): val=self.cleaned_data.get('user') ret=models.Userinfo.objects.filter(user=val) if not ret: return val else: raise ValidationError('用户名以存在!') def clean_phone(self): val=self.cleaned_data.get('phone') import re bb=re.findall('^1[345789][0-9]{9}$', val) print(bb) if bb: return val else: raise ValidationError('手机号格式错误,请输入正确手机号') def clean(self): val=self.cleaned_data.get('pwd') val1=self.cleaned_data.get('pwd1') if val==val1: return val else: raise ValidationError('两次密码不一致')
视图函数的写法上和钩子内容的传送
#注册函数 def reg(request): if request.method=='POST': print(request.POST) reg_obj=Regform(request.POST) if reg_obj.is_valid(): pass else: #上边写了一个全局钩子,想要取出他的值就要在views视图中取出来, # 因为模板语言中没有__all__的属性和方法, # 但是也不能直接这样取数据,a = reg_obj.errors.get('__all__')[0] #当错误字典中没有数据时,不能按索引取出0位置的数据,回报错 所以要这样写 # TypeError: 'NoneType'object is not subscriptable a=reg_obj.errors.get('__all__') 这样取出自定义全局钩子中的数据,不要加 [0] print('>>>>>>>>>',a) #当为空时打印出>>>>>>>>> None 所以不能按索引取出数据 return render(request,'reg.html',{'reg_obj':reg_obj,'a':a}) #实例化一个表单对象,将对象返回给页面是没有数据的表单 reg_obj=Regform() print(reg_obj)
模板语言
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> <style> span{color:red} </style> </head> <body> <form action="" method="post" novalidate> {% csrf_token %} <p>用户名</p> {{ reg_obj.user }} <span>{{ reg_obj.errors.user.0 }}</span> <p>密码</p> {{ reg_obj.pwd }} {# 在这里取出错误信息数据,因为模板语言中如果索引为0的位置没有数据只会不渲染 但是不会报错 #} <span>{{ reg_obj.errors.pwd.0 }}</span> 用这种方法取出错误信息 <p>确认密码</p> {{ reg_obj.pwd1 }}
#这里取出全局钩子中的错误数据,如果没有不会渲染 <span>{{ a.0 }}</span> <span>{{ reg_obj.errors.pwd1.0 }}</span> <span></span> <p>邮箱</p> {{ reg_obj.email }} <span>{{ reg_obj.errors.email.0 }}</span> <p>电话</p> {{ reg_obj.phone }} <span>{{ reg_obj.errors.phone.0 }}</span> {# {% for filed in reg_obj %}#} {# <p>{{ filed.lable }}</p>#} {# {{ field }}#} {# <span>{{ reg_obj.errors.filed.0 }}</span>#} {# {% endfor %}#} <input type="submit"> </form> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script> <script> </script> </body> </html>
ajsx和form表单相结合
else: pwderror=user_info.errors.get('__all__') # print('aaa',user_info.errors) user_info=dict(user_info.errors) #这里user_info.errors实际就是一个字典形式的值,所以在这里将错误信息强转字典 print(user_info) #打印出来的信息如下,是一个键值对,形式 # {'user': ['请输入用户名'], 'pwd': ['请输入用密码'], 'pwd1': ['请确认密码'], # 'nickname': ['请输入昵称'], 'phone': ['请输入用电话'], 'avatar': ['头像不能为空']} li=['user','pwd','pwd1','nickname','phone','avatar','pwderror'] dic={} for i in li: # 判断某字段是否有错误,如果没有的话就给他加一个字段, if i not in user_info: dic[i]={'yesorno':'No'} else: dic[i] = {'yesorno': 'Yes', i: user_info[i]} print(dic) #最后得到的字典如下,没有错误的会加一个 'yesorno':'No'的字段 到后端的时候用户判断此条信息是否有错误,有错误的话打印错误信息 # {'user': {'yesorno': 'No'}(没有错误的这个字段值为No), 'pwd': {'yesorno': 'Yes', 'pwd': ['请输入用密码']}, # 'pwd1': {'yesorno': 'Yes', 'pwd1': ['请确认密码']}, 'nickname': {'yesorno': 'Yes', 'nickname': ['请输入昵称']}, # 'phone': {'yesorno': 'Yes', 'phone': ['请输入用电话']}, 'avatar': {'yesorno': 'Yes', 'avatar': ['头像不能为空']}, # 'pwderror': {'yesorno': 'No'}} user_info=json.dumps(dic) #将字典序列化, # print(user_info) return HttpResponse(user_info) #将序列化的数据传给网页,网页端用data接收
{# 检验用户名是否有误#}
$('[name="user"]').blur(function () {
$.ajax({
url: '/app01/reg/',
type: 'post',
data: {'user':$('[name="user"]').val(), 'csrfmiddlewaretoken': $('input[name="csrfmiddlewaretoken"]').val()},
success: function (data) {
{# 将传过来的字典反序列化#}
var a = JSON.parse(data);
{# 得到yesorno的值#}
var b=a['user']['yesorno'];
console.log(b);
{# 如果值为yes,则表示有错误信息,可以取出错误列表中的索引位置为0的信息#}
if (b==='Yes') {
$('[name="user"]').next().html(a['user']['user'][0])
}
}
})



浙公网安备 33010602011771号