Как вы сериализуете экземпляр модели в Django? - PullRequest
134 голосов
/ 16 апреля 2009

Существует много документации о том, как сериализовать Model QuerySet, но как просто сериализовать в JSON поля экземпляра модели?

Ответы [ 15 ]

212 голосов
/ 20 июля 2010

Вы можете легко использовать список, чтобы обернуть требуемый объект, и это все, что нужно сериализаторам django для его правильной сериализации, например ::

from django.core import serializers

# assuming obj is a model instance
serialized_obj = serializers.serialize('json', [ obj, ])
52 голосов
/ 24 февраля 2016

Если вы имеете дело со списком модельных экземпляров, лучшее, что вы можете сделать, это использовать serializers.serialize(), это будет соответствовать вашим потребностям.

Однако вы должны столкнуться с проблемой при попытке сериализации одного объекта, а не list объектов. Таким образом, чтобы избавиться от различных хаков, просто используйте Django model_to_dict (если я не ошибаюсь, serializers.serialize() тоже полагается на него):

from django.forms.models import model_to_dict

# assuming obj is your model instance
dict_obj = model_to_dict( obj )

Теперь вам нужен только один прямой вызов json.dumps, чтобы сериализовать его в json:

import json
serialized = json.dumps(dict_obj)

Вот и все! :)

41 голосов
/ 14 декабря 2012

Чтобы избежать обертки массива, удалите ее перед возвратом ответа:

import json
from django.core import serializers

def getObject(request, id):
    obj = MyModel.objects.get(pk=id)
    data = serializers.serialize('json', [obj,])
    struct = json.loads(data)
    data = json.dumps(struct[0])
    return HttpResponse(data, mimetype='application/json')

Я тоже нашел этот интересный пост на эту тему:

http://timsaylor.com/convert-django-model-instances-to-dictionaries

Он использует django.forms.models.model_to_dict, который выглядит как идеальный инструмент для работы.

10 голосов
/ 16 апреля 2009

Похоже, что вы спрашиваете, включает в себя сериализацию структуры данных экземпляра модели Django для совместимости. Другие постеры верны: если вы хотите, чтобы сериализованная форма использовалась с приложением python, которое может запрашивать базу данных через API Django, то вы бы хотели сериализовать набор запросов с одним объектом. Если, с другой стороны, вам нужен способ заново наполнить экземпляр модели где-то еще, не касаясь базы данных или не используя Django, то вам нужно проделать небольшую работу.

Вот что я делаю:

Сначала я использую demjson для преобразования. Это было то, что я нашел первым, но это может быть не лучшим. Моя реализация зависит от одной из ее особенностей, но с другими конвертерами должны быть аналогичные способы.

Во-вторых, внедрите метод json_equivalent на всех моделях, которые вам могут потребоваться сериализовать. Это волшебный метод для demjson, но, вероятно, вы захотите подумать о том, какую реализацию вы выберете. Идея состоит в том, что вы возвращаете объект, который напрямую конвертируется в json (то есть массив или словарь). Если вы действительно хотите сделать это автоматически:

def json_equivalent(self):
    dictionary = {}
    for field in self._meta.get_all_field_names()
        dictionary[field] = self.__getattribute__(field)
    return dictionary

Это не поможет вам, если у вас нет абсолютно плоской структуры данных (без ForeignKeys, только цифры и строки в базе данных и т. Д.). В противном случае вам следует серьезно подумать о правильном способе реализации этого метода.

В-третьих, звоните demjson.JSON.encode(instance), и у вас есть то, что вы хотите.

8 голосов
/ 01 июля 2013

Если вы спрашиваете, как сериализовать отдельный объект из модели, и вы знаете , вы получите только один объект в наборе запросов (например, с помощью objects.get), затем используйте что-то вроде:

import django.core.serializers
import django.http
import models

def jsonExample(request,poll_id):
    s = django.core.serializers.serialize('json',[models.Poll.objects.get(id=poll_id)])
    # s is a string with [] around it, so strip them off
    o=s.strip("[]")
    return django.http.HttpResponse(o, mimetype="application/json")

, что даст вам что-то в форме:

{"pk": 1, "model": "polls.poll", "fields": {"pub_date": "2013-06-27T02:29:38.284Z", "question": "What's up?"}}
7 голосов
/ 15 июля 2018

На это есть хороший ответ, и я удивлен, что об этом не упоминалось. С помощью нескольких строк вы можете обрабатывать даты, модели и все остальное.

Создание пользовательского кодировщика, который может работать с моделями:

from django.forms import model_to_dict
from django.core.serializers.json import DjangoJSONEncoder
from django.db.models import Model

class ExtendedEncoder(DjangoJSONEncoder):

    def default(self, o):

        if isinstance(o, Model):
            return model_to_dict(o)

        return super().default(o)

Теперь используйте его, когда используете json.dumps

json.dumps(data, cls=ExtendedEncoder)

Теперь модели, даты и все остальное можно сериализовать, и оно не обязательно должно быть в массиве, сериализировано и не сериализировано

5 голосов
/ 01 апреля 2013

Вот мое решение для этого, которое позволяет вам легко настраивать JSON, а также организовывать связанные записи

Сначала реализуем метод на модели. Я звоню по номеру json, но вы можете называть это как хотите, например ::10000

class Car(Model):
    ...
    def json(self):
        return {
            'manufacturer': self.manufacturer.name,
            'model': self.model,
            'colors': [color.json for color in self.colors.all()],
        }

Тогда в представлении я делаю:

data = [car.json for car in Car.objects.all()]
return HttpResponse(json.dumps(data), content_type='application/json; charset=UTF-8', status=status)
5 голосов
/ 11 апреля 2010

Я решил эту проблему, добавив метод сериализации в мою модель:

def toJSON(self):
    import simplejson
    return simplejson.dumps(dict([(attr, getattr(self, attr)) for attr in [f.name for f in self._meta.fields]]))

Вот подробный эквивалент для тех, кто не любит однострочников:

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 simplejson
    return simplejson.dumps(d)

_meta.fields - упорядоченный список полей модели, доступ к которому можно получить из экземпляров и из самой модели.

4 голосов
/ 09 октября 2016

Используйте список, это решит проблему

Шаг 1:

 result=YOUR_MODELE_NAME.objects.values('PROP1','PROP2').all();

Шаг 2:

 result=list(result)  #after getting data from model convert result to list

Step3:

 return HttpResponse(json.dumps(result), content_type = "application/json")
3 голосов
/ 07 мая 2019

Использование Сериализатор Django с форматом python,

from django.core import serializers

qs = SomeModel.objects.all()
serialized_obj = serializers.serialize(<b>'python'</b>, qs)

В чем разница между форматами json и python?

Формат json вернет результат в виде str, тогда как python вернет результат в list или OrderedDict

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...