1. 程式人生 > >Django 表單 (下) - 序列化操作

Django 表單 (下) - 序列化操作

序列化 django

Django裏面,當我們使用post提交form的時候,如果出現了錯誤,我們可以直接把錯誤通過obj傳回給前端。如果當我們使用Ajax方式和自定義的form提交數據,這個時候就需要在後端把錯誤信息序列化,然後傳回前端進行反序列化了。


對於錯誤信息,django提供了幾種轉換的方式。


第一種是as_json,他可以把整個錯誤信息轉換為字符串的格式,這樣子我們可以直接序列化json.dumps傳到前端去。他的問題在於這個錯誤信息是一個嵌套的字典,意味著在前端需要反序列化2次才能獲取正確的信息。


view.py

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.html

<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的類型,我們手動執行不同的操作

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))


類似的,當我們操作時間數據的時候,默認他沒法序列化,我們可以通過類似的方法進行轉換

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結構的序列化

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這個類型,只寫上邊的三句就可以實現


以上資料出自老男孩的培訓視頻~

本文出自 “麻婆豆腐” 博客,請務必保留此出處http://beanxyz.blog.51cto.com/5570417/1970282

Django 表單 (下) - 序列化操作