day22-Form内置序列化错误信息

一、前言

  今天我们来用个一个ajax的例子,来说明form的验证,还有一个就是,我们json.dumps的只能是python简单的数据类型,但是如果遇到复杂的数据类型,json.dumps是序列化不了的,那这个怎么办呐。我们用什么办法解决呐,下面我们就来学习一下,这个东西,还有一个就是我们在写,views代码的时候,我们可以另外建一个文件夹,所以我们整体的目录结构如下:

-sday22
	-app01  #app名字
		migrations  #初始化数据库的
		views       #写业务代码的
			- __init__.py
			- accounts.py #用户验证
			- blogs.py    #博客业务代码
			- ...
		.....
		forms       #写forms验证的
			- __init__.py
			- froms.py    #专业做forms验证的
			- ....
		....
	- sday22  #项目名
		.....
	- static  #静态资源
		....
	- templates  #模板
		...
	- manage.py

二、用ajax获取内置序列化错误信息

  前提,我们以后的项目编写,都按照上面的目录结构,所以我们的业务代码都是写在view文件夹下的

2.1、路由设置

说明:设置登录的url

from django.urls import path
from app01.views import accounts

urlpatterns = [
    path('login/', accounts.login),
]

2.2、视图函数编写

说明:这边要写很多,这边有from验证,django的序列化的转换,以及登录函数login,为了方便我们写在一个文件里面,但是下面是我分3块去写

1、forms验证

from django import forms
from django.forms import fields,widgets

class LoginForm(forms.Form):
    username = fields.CharField() #这跟login.html中的input标签的name属性的值一致
    password = fields.CharField(
        max_length=64,
        min_length=12
    )

2、定义JsonCustomEncoder类

说明:这个类特意是为了处理无法序列化复杂的数据类型的,上面  result = json.dumps(ret,cls=JsonCustomEncoder) #这边cls 是序列化的时候,对每一个字段序列化的时候,都会调用一个它的default方法,会在下面的login函数中用到

from django.core.exceptions import ValidationError
import json
class JsonCustomEncoder(json.JSONEncoder):  #直接在cls=JsonCustomEncoder类名,去序列化复杂的数据类型
    def default(self,field):
        if isinstance(field,ValidationError):  #field是否是ValidationError的一个对象
            return {'code':field.code,'messages':field.messages}
        else:
            return json.JSONEncoder.default(self,field)

3、login函数

说明:序列化的时候,复杂的数据类型,json是处理不了的,所以需要特殊处理,这边要定义个JsonCustomEncoder类

from django.shortcuts import render,HttpResponse
import json

def login(request):
    ret = {'status':True,'error':None,'data':None}
    if request.method == "GET":
        return render(request,'login.html')
    elif request.method == "POST":
        obj = LoginForm(request.POST)
        if obj.is_valid():
            print(obj.cleaned_data)
        else:
            # print(type(obj.errors))
            # ret['error'] = obj.errors.as_json()  # as_data 帮我返回的是原生的字典
            # print(type(obj.errors.as_data()))
            # for k,v in obj.errors.as_data().items():
            #     print(k,v)
            # ret = {'k1':'v1','k2':ValueError()}  #像这种复杂数据类型,json是不能序列化的,我们只能做局部处理
            #from django.forms.utils import ErrorDict  #通过源码得知:as_data 帮我返回的是原生的字典,as_json()是类似json格式的字符串
            # print(obj.errors.as_json())  #我拿到一个字符串,把这个字符串添加到error中

            # from django.core.exceptions import ValidationError  #看一下这个异常
            ret['error'] = obj.errors.as_data()
        result = json.dumps(ret,cls=JsonCustomEncoder)  #这边cls 是序列化的时候,对每一个字段序列化的时候,都会调用一个它的default方法
        return HttpResponse(json.dumps(result))

2.3、模板编写

说明:模板我们用ajax去请求,然后收到数据处理

<body>
    <form id="fm">
        {% csrf_token %}
        <p><input type="text" name="username" /></p>  #这边username 需要跟 from 里面的字段 是一模一样
        <p><input type="text" name="password" /></p>
        <a id="submit">提交</a>
    </form>

    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        $(function(){
            $('#submit').click(function(){
                $.ajax({
                    url:'/login/',
                    type:'post',
                    data:$('#fm').serialize(),
                    sucess:function(arg){
                        //console.log(arg);
                        arg = JSON.parse(arg);
                        console.log(arg)
                    },
                    error:function(){

                    }
                })
            })
        })
    </script>
</body>

最后返回的数据类型为:

"{\"data\": null, \"status\": true, \"error\": {\"username\": [{\"code\": \"required\", \"messages\": [\"This field is required.\"]}],
 \"password\": [{\"code\": \"required\", \"messages\": [\"This field is required.\"]}]}}"

三、总结

  1. python中的json函数,只能处理 简单的 数据类型,如果要处理复杂的数据类型,比如:datetime、ValidationError等这种复杂的数据类型,需要协助定义:JsonCustomEncoder类,然后json.dumps(ret,cls=JsonCustomEncoder)去引用
  2. python还有其他的复杂的序列化操作:http://www.cnblogs.com/zhangqigao/articles/8990400.html

转载于:https://www.cnblogs.com/zhangqigao/articles/8989193.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值