Існує багато документації про те, як серіалізувати 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-in вещества-to-dic Dictionary
Він використовує 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, то вам доведеться трохи попрацювати.
Ось що я роблю:
По-перше, я використовую 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)
і у вас є те, що ви хочете.
Якщо ви запитуєте, як серіалізувати один об'єкт з моделі, і ви знаєте, що збираєтесь отримати лише один об’єкт у наборі запитів (наприклад, за допомогою object.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
випуск джанго, тому цього може бути не в попередніх версіях.
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
для цього. Якась конкретна причина не використовувати серіалізувати набір запитів?