2010-01-19 25 views
4

現在我已經使用json序列化器,它工作得很好。Django:json序列化使用defer()或僅使用()的查詢集

我不得不修改我的疑問,我開始使用only() & defer()過濾器,像這樣 -

retObj = OBJModel.objects.defer("create_dt").filter(loged_in_dt__gte=dtStart) 

我已經做了上面,突然JSON序列將返回空字段後 -

{"pk": 19047, "model": "OBJModel_deferred_create_dt", "fields": {}} 

如果我刪除了defer(),序列化程序會正確提供所有數據。

import json 
from django.utils import simplejson 
from django.core import serializers 
json_serializer = serializers.get_serializer("json")() 
retObj = OBJModel.objects.defer("create_dt").filter(loged_in_dt__gte=dtStart) 
json_serializer.serialize(retObj, ensure_ascii=False) 

我已經在這一段時間裏撓了撓頭。任何見解都會很棒。

注意:我使用Django 1.1

+0

什麼類型的字段是create_dt?看看Django的門票,只有一些錯誤和延期。也許你是其中之一,或者是一個新的bug。我不明白爲什麼它會這樣做,而不是一個錯誤。我希望我被證明是錯誤的,但:) – Bartek

+0

它的'models.DateTimeField(auto_now_add = True)'。我希望我沒有隱藏一個bug .. – PlanetUnknown

回答

2

我很困惑,你如何期望序列化的問候行爲遞延領域......這可能是我想的東西.. 。

doc for json serialization說:

請注意,如果您是直接使用該模塊序列化,並不是所有的Django的輸出可以被傳遞給未修改simplejson。特別是懶惰的翻譯對象需要爲它們編寫一個特殊的編碼器。

該文檔談論懶惰翻譯,但我認爲任何懶惰的操作適用。

我認爲你所看到的僅僅是正確的輸出,如果你沒有寫出某種特殊的編碼器來處理(訪問)延期字段的正確值。

編輯你的評論後:啊,我錯過了沒有其他領域正在編碼的事實。其他領域的類型是什麼?我們可以看看你的模型嗎? FK和M2M領域由默認編碼器的處理方式不同 - 但我沒有看到django.core.serializers.python.Serializerdjango.core.serializers.json.Serializer任何可以解釋爲什麼其他非遞延字段不編碼...經過一番深入調查

編輯:上面的json負載中的OBJModel_deferred_create_dt讓我進一步挖掘了一下。看起來這是在django的基礎Model類中從__reduce__方法調用django.db.models.queryutils.deferred_class_factory()的結果。 deferred_class_factory()

返回一個類對象,它是指定的「attrs」被DeferredAttribute對象替換的「model」的副本。 「pk_value」將延遲屬性綁定到模型的特定實例。

在這裏,事情會變得複雜(我!):在現實中,酸洗正在針對proxy model做了您的實際OBJModel。這個代理模型應該返回 - 當被問到時 - 原始模型的非延期字段。但在你的情況下,它似乎不是。

我會嘗試設置一個小測試,看看我是否可以複製該問題。

+0

嗯..當我們推遲一個領域,該領域沒有得到檢索。但其餘數據被檢索。因此,當你將它傳遞給JSON時,它實際上應該對它進行編碼。我可以理解它不編碼延遲字段,但未延遲字段已經存在。說啥 ? – PlanetUnknown

0

我在想這是一種錯誤。以下是解決方法。在調用序列化之前執行此操作。你會受到性能影響,但可能會少於序列化整個對象。

for obj in qs: 
    for attr in qs.query.deferred_loading[0]: 
     obj._meta.local_fields.append(qs.model._meta.get_field(attr))