Django 表单 (下) - 序列化操做

Django里面,当咱们使用post提交form的时候,若是出现了错误,咱们能够直接把错误经过obj传回给前端。若是当咱们使用Ajax方式和自定义的form提交数据,这个时候就须要在后端把错误信息序列化,而后传回前端进行反序列化了。html


对于错误信息,django提供了几种转换的方式。前端


第一种是as_json,他能够把整个错误信息转换为字符串的格式,这样子咱们能够直接序列化json.dumps传到前端去。他的问题在于这个错误信息是一个嵌套的字典,意味着在前端须要反序列化2次才能获取正确的信息。python


view.pyjquery

from django import formsfrom django.forms import widgets, fields
class LoginForm(forms.Form):
    username = fields.CharField()
    password = fields.CharField(
        max_length=64,
        min_length=12
    )
def login(request):
    import json
    res = {'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.cleand_data)        
        else:            
        # print(obj.errors, type(obj.errors))
            res['error'] = obj.errors.as_json()  # 转为json格式
            return HttpResponse(json.dumps(res))


login.htmlajax

<body>
    <form id="fm">
        {% csrf_token %}        
        <p><input type="text" name="username" /></p>
        <p><input type="password" name="password" /></p>
        <a id="submit">ajax提交</a>
    </form>
    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        // 页面框架加载完自动执行
        $('#submit').click(function(){
            $.ajax({
                url:'/login.html',
                type:'POST',
                data:$('#fm').serialize(),
                success:function(arg){
                    console.log(arg);
                    arg = JSON.parse(arg);  // 转为字典
                    console.log(arg);
                },
                error: function(){

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



一种优化的方法是自定义一个Json的报错格式,经过判断isinstance(filed, XXX) 里面 XXX的类型,咱们手动执行不一样的操做django

from django import forms
from django.forms import widgets, fields
class LoginForm(forms.Form):
    username = fields.CharField()
    password = fields.CharField(
        max_length=64,
        min_length=12
    )

# 序列化,转换为指定数据类型
import json
from django.core.exceptions import ValidationError

class JsonCustomEncoder(json.JSONEncoder):
    def default(self, field):
        if isinstance(field, ValidationError):
            return {'code':field.code, 'messages': field.messages}
        else:
            return json.JSONEncoder.default(self, field)

def login(request):
    res = {'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.cleand_data)
        else:
            # print(obj.errors, type(obj.errors))
            # res['error'] = obj.errors.as_json()  # 转为json格式
            print(type(obj.errors.as_data()))
            for k,v in obj.errors.as_data().items():
                print(k,v)  # 这里v是ValidationError类型,不能序列化
            res['error'] = obj.errors.as_data()
        result = json.dumps(res, cls=JsonCustomEncoder)
        return HttpResponse(json.dumps(result))


相似的,当咱们操做时间数据的时候,默认他无法序列化,咱们能够经过相似的方法进行转换json

import json 
from datetime import date 
from datetime import datetime 
class JsonCustomEncoder(json.JSONEncoder): 
    def default(self, field): 
        if isinstance(field, datetime): 
            return o.strftime('%Y-%m-%d %H:%M:%S') 
        elif isinstance(field, date): 
            return o.strftime('%Y-%m-%d')   # 转成字符串类型
        else: 
            return json.JSONEncoder.default(self, field) 
v = {'k':'123', "k1":datetime.datetime.now()}   
ds = json.dumps(v, cls=JsonCustomEncoder)


最后看看其余类型的序列化后端

对QuerySet的序列化框架

from django.core import serializers
v = models.tb.objects.all()
data = serializers.serialize("json", v)


对QuerySet value结构的序列化ide

import json
from datetime import date
from datetime import datetime
class JsonCustomEncoder(json.JSONEncoder):
    def default(self, field):
        if isinstance(field, datetime):
            return field.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(field, date):
            return field.strftime('%Y-%m-%d')
        else:
            return json.JSONEncoder.default(self, field)
v = models.tb.objects.values('id','name','ctime')
v = list(v)  # 把(相似列表的queryset类型)转换为列表
v = json.dumps(v,cls=JsonCustomEncoder)  # 这里cls只对ctime操做。
# 若是没有ctime这个类型,只写上边的三句就能够实现


以上资料出自老男孩的培训视频~

相关文章
相关标签/搜索