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


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

相關文章
相關標籤/搜索