Существует много документации о том, как сериализовать Model QuerySet, но как просто сериализовать в JSON поля экземпляра модели?
Существует много документации о том, как сериализовать Model QuerySet, но как просто сериализовать в JSON поля экземпляра модели?
Ответы:
Вы можете легко использовать список, чтобы обернуть требуемый объект, и это все, что нужно сериализаторам django для правильной сериализации, например:
from django.core import serializers
# assuming obj is a model instance
serialized_obj = serializers.serialize('json', [ obj, ])
[0]
в конце своей последней строки, как предложено @DavorLucic? И нет необходимости в конце запятой в вашем списке буквально (ради любви к PEP8;).
Если вы имеете дело со списком модельных экземпляров, лучшее, что вы можете сделать, это использовать 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)
Это оно! :)
datetime
полями. Решил это так, json.loads(serialize('json', [obj]))[0]
пока сериализатор естьdjango.core.serializers.serialize
Чтобы избежать обертки массива, удалите ее перед возвратом ответа:
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, который выглядит как идеальный инструмент для работы.
На это есть хороший ответ, и я удивлен, что об этом не упоминалось. С помощью нескольких строк вы можете обрабатывать даты, модели и все остальное.
Создайте собственный кодировщик, который может работать с моделями:
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)
Теперь модели, даты и все остальное можно сериализовать, и это не обязательно должно быть в массиве, или сериализовано, и не сериализовано. Все, что у вас есть, может быть добавлено в default
метод.
Вы даже можете использовать родной JsonResponse Django следующим образом:
from django.http import JsonResponse
JsonResponse(data, encoder=ExtendedEncoder)
``
json.dumps
и с другими json.dump
. Таким образом, вам не нужно изменять рабочий процесс приложения, потому что вы используете пользовательские объекты или добавляете другой вызов метода до преобразования в json. Просто добавьте свой код преобразования в кодировщик, и вы готовы к работе.
Похоже, что вы спрашиваете, включает в себя сериализацию структуры данных экземпляра модели 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)
и вы получите то, что хотите.
Если вы спрашиваете, как сериализовать отдельный объект из модели и знаете , что получите только один объект в наборе запросов (например, с помощью 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?"}}
Я решил эту проблему, добавив метод сериализации в мою модель:
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
упорядоченный список полей модели, доступ к которому можно получить из экземпляров и из самой модели.
Вот мое решение для этого, которое позволяет вам легко настроить JSON, а также организовать связанные записи
Сначала реализуем метод на модели. Я звоню, json
но вы можете называть это как хотите, например:
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)
car.json()
Используйте список, это решит проблему
Шаг 1:
result=YOUR_MODELE_NAME.objects.values('PROP1','PROP2').all();
Шаг 2:
result=list(result) #after getting data from model convert result to list
Шаг 3:
return HttpResponse(json.dumps(result), content_type = "application/json")
Для сериализации и десериализации используйте следующее:
from django.core import serializers
serial = serializers.serialize("json", [obj])
...
# .next() pulls the first object out of the generator
# .object retrieves django object the object from the DeserializedObject
obj = next(serializers.deserialize("json", serial)).object
.values()
это то, что мне нужно для преобразования экземпляра модели в JSON.
.values () документация: https://docs.djangoproject.com/en/3.0/ref/models/querysets/#values
Пример использования с моделью под названием Project .
Примечание: я использую Django Rest Framework
@csrf_exempt
@api_view(["GET"])
def get_project(request):
id = request.query_params['id']
data = Project.objects.filter(id=id).values()
if len(data) == 0:
return JsonResponse(status=404, data={'message': 'Project with id {} not found.'.format(id)})
return JsonResponse(data[0])
Результат от действительного идентификатора:
{
"id": 47,
"title": "Project Name",
"description": "",
"created_at": "2020-01-21T18:13:49.693Z",
}
python
форматом,from django.core import serializers
qs = SomeModel.objects.all()
serialized_obj = serializers.serialize('python', qs)
json
иpython
формат?json
Формат будет возвращать результат , как str
тогда python
будет возвращать результат в любом list
илиOrderedDict
OrderedDict
, неdict
Не похоже, что вы можете сериализовать экземпляр, вам нужно будет сериализовать QuerySet одного объекта.
from django.core import serializers
from models import *
def getUser(request):
return HttpResponse(json(Users.objects.filter(id=88)))
У меня закончился svn
выпуск django, так что это может быть не так в более ранних версиях.
ville = UneVille.objects.get(nom='lihlihlihlih')
....
blablablab
.......
return HttpResponse(simplejson.dumps(ville.__dict__))
Я возвращаю диктат моего дела
поэтому он возвращает что-то вроде {'field1': value, "field2": value, ....}
TypeError: <django.db.models.base.ModelState object at 0x7f2b3bf62310> is not JSON serializable
Все эти ответы были немного хакерскими по сравнению с тем, что я ожидал бы от фреймворка, самого простого метода, я думаю, если вы используете остальную фреймворк:
rep = YourSerializerClass().to_representation(your_instance)
json.dumps(rep)
Он использует Serializer напрямую, уважая поля, которые вы на нем определили, а также любые ассоциации и т. Д.
django.core
для этого. Любая конкретная причина не использовать сериализовать набор запросов?