Django: json сериализует набор запросов, который использует defer () или only () - PullRequest
5 голосов
/ 19 января 2010

Теперь я использую сериализатор json, и он прекрасно работает.

Мне пришлось изменить мои запросы, когда я начал использовать фильтры 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

Ответы [ 2 ]

2 голосов
/ 20 января 2010

Я не понимаю, как можно ожидать, что сериализатор будет вести себя в отношении отложенных полей ... Возможно, я что-то упустил ...

Документ для сериализации JSON говорит:

Имейте в виду, что если вы сериализуете с использованием этого модуля напрямую, не все выходные данные Django могут быть переданы без изменений в simplejson. В частности, ленивым объектам перевода нужен специальный кодер, написанный для них.

Док говорит о ленивых переводах, но я думаю, что любая ленивая операция применима.

Я думаю, что вы видите только правильный вывод, если вы не написали специальный кодер, который позаботится о получении (доступе) правильного значения для отложенных полей.

Изменить после вашего комментария: Ах, я упустил тот факт, что другие поля не кодируются. Какие типы других полей? Можем ли мы увидеть вашу модель? Поля FK и M2M обрабатываются кодером по умолчанию по-разному, но я ничего не вижу в django.core.serializers.python.Serializer или django.core.serializers.json.Serializer, что объясняло бы, почему другие неотложенные поля не кодируются ...

Правка после некоторого дальнейшего исследования: OBJModel_deferred_create_dt в вашей полезной нагрузке json выше заставил меня копать немного дальше. Похоже, это результат вызова django.db.models.queryutils.deferred_class_factory() из метода __reduce__ в базовом классе модели django. deferred_class_factory():

Возвращает объект класса, который является копией «model» с указанными «attrs», заменяемыми объектами DeferredAttribute. «Pk_value» связывает отложенные атрибуты с конкретным экземпляром модели.

Вот где все становится мутно (для меня!): На самом деле травление делается против прокси-модели для вашего фактического OBJModel. Эта прокси-модель должна возвращать - когда запрашивается - неотложенные поля исходной модели. Но в вашем случае кажется, что это не так.

Я попытаюсь настроить небольшой тест и посмотреть, смогу ли я воспроизвести проблему.

0 голосов
/ 23 февраля 2011

Я думаю, что это какая-то ошибка. Ниже представлен обходной путь. Сделайте это, прежде чем вызывать serialize. Вы получите снижение производительности, но, вероятно, меньше, чем сериализация всего объекта.

for obj in qs:
    for attr in qs.query.deferred_loading[0]:
        obj._meta.local_fields.append(qs.model._meta.get_field(attr))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...