中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

django model object序列化的示例分析

發布時間:2021-06-16 15:05:38 來源:億速云 閱讀:114 作者:小新 欄目:開發技術

這篇文章主要為大家展示了“django model object序列化的示例分析”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“django model object序列化的示例分析”這篇文章吧。

提到序列化與反序列化,通常會想到 json ,xml .在J2EE的開發中,這是很常用的技術,比如一個java class與xml之間的序列化與反序列化,我們可以通過 xstream來實現,如果是與json之間的轉換,我們可以通過 gson.jar或者jsonlib.jar 來實現。方法很多,也是常見的方法。

但在python 中,我們常用的是json 的序列化,python2.7 已經包含了json package,這個也是從simplejson 基礎上改變而來。這個json 包主要提供了dump,load 來實現dict 與 字符串之間的序列化與反序列化,這很方便的可以完成,可以參考這篇文章python json。但現在的問題是,這個json包不能序列化 django 的models 里面的對象的實例。

經過分析,網絡搜索,發現有如下解決方案.

利用 from django.core import serializers 的方法實現

from django.core import serializers
data = serializers.serialize("json", SomeModel.objects.all())
data1 = serializers.serialize("json", SomeModel.objects.filter(myfield1=myvalue))

上面兩個是沒有問題的,因為序列化的對象是 Queryset, 因此是成功的。但如果是用SomeModel.objects.get(id=myid) 得到一個具體的實例的時候,問題就來了

data = serializers.serialize("json", SomeModel.objects.get(id=myid))

肯定會出現如下錯誤:

for obj in queryset: TypeError: 'SomeModel' object is not iterable

一看錯誤就知道,因為 SomeModel.objects.get(id=myid) 返回的是一個具體的實例,而不是一個集合對象,因此是不可以 iterable 的。所以報錯。

從上面的分析可以看出 django的 serializers 只支持 queryset,而不支持model的實例,那么怎么實現呢?

1.我們自己把這個單個對象模擬成一個集合,然后去掉前后的"[""]"符號,就可以了。

from django.utils import simplejson
from django.db import models
from django.core.serializers import serialize,deserialize
from django.db.models.query import QuerySet
from django.test import TestCase

class MyEncoder(simplejson.JSONEncoder):
   """ 繼承自simplejson的編碼基類,用于處理復雜類型的編碼
   """
   def default(self,obj):
       if isinstance(obj,QuerySet):
         """ Queryset實例
         直接使用Django內置的序列化工具進行序列化
         但是如果直接返回serialize('json',obj)
         則在simplejson序列化時會被從當成字符串處理
         則會多出前后的雙引號
         因此這里先獲得序列化后的對象
         然后再用simplejson反序列化一次
         得到一個標準的字典(dict)對象
         """
         return simplejson.loads(serialize('json',obj))
       if isinstance(obj,models.Model):
         """
         如果傳入的是單個對象,區別于QuerySet的就是
         Django不支持序列化單個對象
         因此,首先用單個對象來構造一個只有一個對象的數組
         這是就可以看做是QuerySet對象
         然后此時再用Django來進行序列化
         就如同處理QuerySet一樣
         但是由于序列化QuerySet會被'[]'所包圍
         因此使用string[1:-1]來去除
         由于序列化QuerySet而帶入的'[]'
         """
         return simplejson.loads(serialize('json',[obj])[1:-1])
       if hasattr(obj, 'isoformat'):
         #處理日期類型
         return obj.isoformat()
       return simplejson.JSONEncoder.default(self,obj)

def jsonBack(json):
   """  進行Json字符串的反序列化
     一般來說,從網絡得回的POST(或者GET)
     參數中所包含json數據
     例如,用POST傳過來的參數中有一個key value鍵值對為
     request.POST['update']
     = "[{pk:1,name:'changename'},{pk:2,name:'changename2'}]"
     要將這個value進行反序列化
     則可以使用Django內置的序列化與反序列化
     但是問題在于
     傳回的有可能是代表單個對象的json字符串
     如:
     request.POST['update'] = "{pk:1,name:'changename'}"
     這是,由于Django無法處理單個對象
     因此要做適當的處理
     將其模擬成一個數組,也就是用'[]'進行包圍
     再進行反序列化
   """
   if json[0] == '[':
     return deserialize('json',json)
   else:
     return deserialize('json','[' + json +']')

def getJson(**args):
   """  使用MyEncoder這個自定義的規則類來序列化對象
   """
   result = dict(args)
   return simplejson.dumps(result,cls=MyEncoder)

在上面的例子中,自定義了一個序列化規則類MyEncoder,用來處理集合或者集合對象,然后實現了一個可變參數的工具方法getJson,用于傳入多個參數,并將其一同序列化。另外還有一個反序列化對象的方法jsonBack,接受一個代表對象或者對象集合的json而返回一個對象集合。這樣一來就可以很好的使用配合SimpleJson和Django來完成序列化工作了

2.直接利用python 2.7 提供的json包,或者用simplejson都可以

首先,你需要在django model的定義中增加一個方法toJSON,利用了django model 能訪問 _meta.fields 得到相關屬性而得到,例子如下

class Category(models.Model):
  autoid = models.AutoField(primary_key=True)
  email=models.CharField(max_length=150,blank=False)
  comtype=models.CharField(max_length=20,blank=False)
  catname=models.CharField(max_length=150,blank=False) 
  
  def __unicode__(self):
    return '%s' % (self.catname)
  
  def toJSON(self):
    import json
    return json.dumps(dict([(attr, getattr(self, attr)) for attr in [f.name for f in self._meta.fields]]))

現在用django查出數據,并轉換成json

row=models.Category.objects.get(autoid=23) print row.toJSON()

你會發現,成功轉換了。當然,這個toJSON方法,如果要求可讀性比較好的話,可以這樣寫

def toJSON(self):
  fields = []
  for field in self._meta.fields:
    fields.append(field.name)

  d = {}
  for attr in fields:
    d[attr] = getattr(self, attr)

  import json
  return json.dumps(d)

補充知識:django模型類序列化器 ModelSerializer

1. 定義

比如我們創建一個BookInfoSerializer

class BookInfoSerializer(serializers.ModelSerializer):
  """圖書數據序列化器"""
  class Meta:
    model = BookInfo
    fields = '__all__'

model 指明參照哪個模型類

fields 指明為模型類的哪些字段生成

2. 指定字段

1) 使用fields來明確字段,__all__表名包含所有字段,也可以寫明具體哪些字段,如

class BookInfoSerializer(serializers.ModelSerializer):
  """圖書數據序列化器"""
  class Meta:
    model = BookInfo
    fields = ('id', 'btitle', 'bpub_date')

2) 使用exclude可以明確排除掉哪些字段

class BookInfoSerializer(serializers.ModelSerializer):
  """圖書數據序列化器"""
  class Meta:
    model = BookInfo
    exclude = ('image',)

3) 默認ModelSerializer使用主鍵作為關聯字段,但是我們可以使用depth來簡單的生成嵌套表示,depth應該是整數,表明嵌套的層級數量。如:

class HeroInfoSerializer2(serializers.ModelSerializer):
  class Meta:
    model = HeroInfo
    fields = '__all__'
    depth = 1

4) 指明只讀字段

可以通過read_only_fields指明只讀字段,即僅用于序列化輸出的字段

3. 添加額外參數

我們可以使用extra_kwargs參數為ModelSerializer添加或修改原有的選項參數

class BookInfoSerializer(serializers.ModelSerializer):
  """圖書數據序列化器"""
  class Meta:
    model = BookInfo
    fields = ('id', 'btitle', 'bpub_date', 'bread', 'bcomment')
    extra_kwargs = {
      'bread': {'min_value': 0, 'required': True},
      'bcomment': {'min_value': 0, 'required': True},
    }

以上是“django model object序列化的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

泰顺县| 洛阳市| 昌宁县| 乌拉特中旗| 巴林左旗| 浪卡子县| 衡阳县| 新疆| 隆尧县| 金乡县| 扬州市| 湄潭县| 漯河市| 武穴市| 阿城市| 阿拉善盟| 文成县| 武夷山市| 天等县| 望奎县| 搜索| 深水埗区| 元江| 十堰市| 卓资县| 井研县| 水富县| 都兰县| 波密县| 巴彦县| 股票| 汾阳市| 剑川县| 集安市| 英山县| 邯郸市| 宁都县| 金溪县| 孟州市| 夏邑县| 桦南县|