Django之Form表单验证及Ajax验证方式汇总

一、Form表单验证:

原理:在Form表单提交到Views后台时,利用Django特有的验证模版技术(实质上实现验证功能的类)对表单数据进行验证,然后将结果返回到页面上。

html页面代码如下:

<form method="post" action="/login.html">
    <p>
        <input type="text" name="user" placeholder="用户名">
        <!与后台绑定的用户名错误信息>
        <span>{{ obj_login_form.errors.user.0 }}</span>
    </p>
    <p>
        <input type="text" name="email" placeholder="邮箱">
        <!与后台绑定的邮箱错误信息>
        <span>{{ obj_login_form.errors.email.0 }}</span>
    </p>
    <input type="submit" value="提交">
</form>

后台views代码:

from django import forms
class Login_Form(forms.Form):
    # 与前台名称一致的用户名字段,Django内置的普通str验证方法,增加验证最小长度为3
    user=forms.CharField(min_length=3)
    # django内置的Email验证方法
    email=forms.EmailField()


def login(req):
    if req.method=='GET':
        return render(req,'login.html')
    elif req.method=='POST':
        # 将表单数据放入Login_Form中
        obj_login_form=Login_Form(req.POST)
        # 通过is_valid()方法验证,返回是否有错误信息
        if obj_login_form.is_valid():
            # 当验证通过后打印通过的数据
            print(obj_login_form.clean())
        else:
            # 打印验证失败的错误信息
            print(obj_login_form.errors)
        return render(req,'login.html',{'obj_login_form':obj_login_form})

注意:

定义的验证类中验证的字段名与前台页面需要验证的字段名必须一致。Django实现了前台模版调用后台内容为空时自动忽略,因此在get请求时即使没有将{'obj_login_form':obj_login_form}传给前台页面,也不会报错。

当前验证效果:

将验证错误信息改为中文,验证模版代码需要修改为如下:

from django import forms
class Login_Form(forms.Form):
    # 与前台名称一致的用户名字段,Django内置的普通str验证方法,增加验证最小长度为3
    user=forms.CharField(min_length=3,error_messages={'required':'用户名不能为空','min_length':'用户名长度不能小于3'})
    # django内置的Email验证方法
    email=forms.EmailField(error_messages={'required':'用户名不能为空','invalid':'邮箱格式有误'})

实现验证完后页面刷新也不请空数据,需做以下两处修改:

后台Get请求时调用空的验证类:

    if req.method=='GET':
        obj_login_form=Login_Form()
        return render(req,'login.html',{'obj_login_form':obj_login_form})

前台将<input>标签改为Django自动生成的,代码如下:

<form method="post" action="/login.html">
    <p>
        <!"用户名">
        {{ obj_login_form.user }}
        <!与后台绑定的用户名错误信息>
        <span>{{ obj_login_form.errors.user.0 }}</span>
    </p>
    <p>
        <!"邮箱">
         {{ obj_login_form.email }}
        <!与后台绑定的邮箱错误信息>
        <span>{{ obj_login_form.errors.email.0 }}</span>
    </p>
    <input type="submit" value="提交">

二、Ajax方式实现:

原理:通过Ajax将数据提交到后台,后台返回json类型的错误数据展现在前台页面上。

后台返回的错误信息定义如下:

error_list={'status':True,'errors':None}

html代码如下:

<body>
<form id="f1">
    <p>
        <input type="text" name="user" placeholder="用户名">
    </p>
    <p>
        <input type="text" name="email" placeholder="邮箱">
    </p>
    <input type="button" value="提交" id="btn_sumit">
</form>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
    $(function () {
        $('#btn_sumit').click(function () {
            $.ajax({
                url:'/ajax_login.html',
                type:'post',
                //将form表单的数据序列化后传给后台
                data:$('#f1').serialize(),
                dataType:'json',
                success:function (arg) {
                    console.log(arg);
                }
            })
        })
    })
</script>
</body>

验证类实例对象的错误列表errors有多种形式,常用的转换方法有as_json()和as_data()。

1、当使用as_json()时,由于返回给前台的错误信息是json里又套了一层json,因此前台js需要做json解析。

后台代码如下:

import json
def ajax_login(req):
    if req.method == 'GET':       
        return render(req, 'login_js.html')
    elif req.method == 'POST':
        error_list={'status':True,'errors':None}
        # 将表单数据放入Login_Form中
        obj_login_form = Login_Form(req.POST)
        # 通过is_valid()方法验证,返回是否有错误信息
        if obj_login_form.is_valid():
            # 当验证通过后打印通过的数据
            print(obj_login_form.clean())
        else:
            error_list['status']=False
            # 将错误信息转换为json格式
            error_list['errors']=obj_login_form.errors.as_json()
            # 将返回到前台的数据转换为json
        return HttpResponse(json.dumps(error_list))

前台js代码如下:

<script>
    $(function () {
        $('#btn_sumit').click(function () {
            $.ajax({
                url:'/ajax_login.html',
                type:'post',
                //将form表单的数据序列化后传给后台
                data:$('#f1').serialize(),
                dataType:'json',
                success:function (arg) {
                    if(arg.status){
                        console.log('无验证错误信息')
                    }
                    else {
                        //由于后台返回的值是json中套json,因此此处需要再做一次json解析
                        var error_list=JSON.parse(arg.errors)

                        //循环遍历错误列表,自动生成span标签承载错误信息
                        $.each(error_list,function (itemName, item) {
                         var span=  document.createElement('span');
                         span.innerHTML=item[0].message;//获取第一条错误信息
                         $('input[name='+itemName+']').after(span);
                        })
                    }
                }
            })
        })
    })
</script>

2、当使用as_data()时,由于error_list['errors']['email'][0]的类型是'django.core.exceptions.ValidationError',因此需要做一次json转换,完整代码如下:

import json
def ajax_login(req):
    if req.method == 'GET':
        return render(req, 'login_js.html')
    elif req.method == 'POST':
        error_list={'status':True,'errors':None}
        # 将表单数据放入Login_Form中
        obj_login_form = Login_Form(req.POST)
        # 通过is_valid()方法验证,返回是否有错误信息
        if obj_login_form.is_valid():
            # 当验证通过后打印通过的数据
            print(obj_login_form.clean())
        else:
            error_list['status']=False
            # 将错误信息转换为json格式
            error_list['errors']=obj_login_form.errors.as_data()

            print(type(error_list['errors']),error_list['errors']) #error_list['errors']['email']
            print(type(error_list['errors']['email']),error_list['errors']['email'])#<class 'list'> [ValidationError(['用户名不能为空'])]
            print(type(error_list['errors']['email'][0]),error_list['errors']['email'][0])#<class 'django.core.exceptions.ValidationError'> ['用户名不能为空']
            # 将返回到前台的数据转换为json
        return HttpResponse(json.dumps(error_list,cls=error_json_encoder))

from django.core.exceptions import ValidationError
class error_json_encoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o,ValidationError):
            # 如果是ValidationError类型,则将其转换为字典
            return {'code':o.code,'message':o.message}
        else:
            # 如果不是则调用父类方法
            return super(error_json_encoder,self).default(self,o)

由于后台返回的json只有一级,因此前台js无需再转换为json对象再处理,因此前台js为:

<script>
    $(function () {
        $('#btn_sumit').click(function () {
            $.ajax({
                url:'/ajax_login.html',
                type:'post',
                //将form表单的数据序列化后传给后台
                data:$('#f1').serialize(),
                dataType:'json',
                success:function (arg) {
                    if(arg.status){
                        console.log('无验证错误信息')
                    }
                    else {
                       
                        var error_list=arg.errors;

                        //循环遍历错误列表,自动生成span标签承载错误信息
                        $.each(error_list,function (itemName, item) {
                         var span=  document.createElement('span');
                         span.innerHTML=item[0].message;//获取第一条错误信息
                         $('input[name='+itemName+']').after(span);
                        })
                    }
                }
            })
        })
    })
</script>

完整源码请见:

Django之Form表单验证及Ajax验证方式汇总

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现Django中自定义的表单多级联动,需要使用到`ModelForm`和JavaScript来实现。 首先,我们需要创建一个ModelForm,用于实现表单的自定义字段和验证规则。 ```python from django import forms from .models import ModelA, ModelB class MyForm(forms.ModelForm): class Meta: model = ModelA fields = '__all__' # 可根据实际需求选择需要的字段 def __init__(self, *args, **kwargs): super(MyForm, self).__init__(*args, **kwargs) self.fields['second_model'] = forms.ModelChoiceField(queryset=ModelB.objects.none()) if 'first_model' in self.data: try: first_model_id = int(self.data.get('first_model')) self.fields['second_model'].queryset = ModelB.objects.filter(first_model_id=first_model_id) except (ValueError, TypeError): pass elif self.instance.pk: self.fields['second_model'].queryset = self.instance.first_model.modelb_set.order_by('name') ``` 在上面的例子中,`ModelA`是第一个模型,`ModelB`是第二个模型。在`MyForm`类的初始化方法中,根据`first_model`字段的值动态更新`second_model`字段的queryset,实现了多级联动。 接下来,我们需要在模板中添加HTML和JavaScript来实现多级联动效果。 ```html <form method="POST" action=""> {% csrf_token %} {{ form.as_p }} <button type="submit">Submit</button> </form> <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> <script> $(document).ready(function() { $('#id_first_model').change(function() { var url = $(this).attr('data-href'); var first_model_id = $(this).val(); $.ajax({ url: url, data: { 'first_model_id': first_model_id }, success: function(data) { $('#id_second_model').html(data); } }); }); }); </script> ``` 在上面的例子中,我们使用了jQuery来监听`first_model`字段的变化事件。当`first_model`字段的值发生改变时,执行AJAX请求,获取到对应`second_model`字段的选项,并更新页面上的`second_model`字段。 总结来说,我们通过自定义的表单类`MyForm`来实现外键的多级联动,然后通过JavaScript的AJAX请求和动态更新页面的选项来实现表单的多级联动效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值