如何在Django中序列化一个模型实例?

有很多关于如何序列化模型QuerySet的文档,但是如何将模型实例的字段序列化为JSON呢?

221514 次浏览

似乎你不能序列化实例,你必须序列化一个对象的QuerySet。

from django.core import serializers
from models import *


def getUser(request):
return HttpResponse(json(Users.objects.filter(id=88)))

我运行了django的svn版本,所以这可能不是在早期版本。

听起来,您所询问的问题涉及序列化Django模型实例的数据结构以实现互操作性。其他的海报是正确的:如果你想要序列化的表单与python应用程序一起使用,可以通过Django的api查询数据库,那么你需要用一个对象序列化一个queryset。另一方面,如果您需要的是一种在不接触数据库或不使用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),你就得到了你想要的。

ville = UneVille.objects.get(nom='lihlihlihlih')
....
blablablab
.......


return HttpResponse(simplejson.dumps(ville.__dict__))

我返回我实例的字典

所以它会返回类似{'field1':value,"field2":value,....}

我通过在我的模型中添加一个序列化方法来解决这个问题:

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是一个模型字段的有序列表,可以从实例和模型本身访问。

你可以很容易地使用一个列表来包装所需的对象,这就是django序列化器正确序列化它所需要的,例如:

from django.core import serializers


# assuming obj is a model instance
serialized_obj = serializers.serialize('json', [ obj, ])

这样怎么样:

def ins2dic(obj):
SubDic = obj.__dict__
del SubDic['id']
del SubDic['_state']
return SubDic

或者排除你不想要的东西。

为了避免数组包装器,在返回响应之前删除它:

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 < a href = " http://timsaylor.com/convert-django-model-instances-to-dictionaries " > < / >

它使用django.forms.models。Model_to_dict,它看起来是完成这项工作的完美工具。

下面是我的解决方案,它允许您轻松地自定义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)

如果你正在询问如何从一个模型中序列化一个对象,而你知道你只会在查询集中获得一个对象(例如,使用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?"}}

要序列化和反序列化,请使用以下命令:

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

如果你在处理一个模型实例列表,你能做的最好的是使用serializers.serialize(),它会完美地满足你的需要。

然而,你将面临一个问题,试图序列化一个对象,而不是对象的list。这样,为了摆脱不同的hack,只需使用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)

就是这样!:)

使用列表,它将解决问题

步骤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.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方法中。

你甚至可以这样使用Django的原生JsonResponse:

from django.http import JsonResponse


JsonResponse(data, encoder=ExtendedEncoder)

使用带有python格式的< >强Django序列化器< / >强

from django.core import serializers


qs = SomeModel.objects.all()
serialized_obj = serializers.serialize('python', qs)

< >强json < / >强< >强python < / >强格式有什么区别?

json格式将返回结果为< >强str < / >强,而< >强python < / >强格式将返回结果为< >强list < / >强< >强OrderedDict < / >强

如果你想将单一模型对象作为json响应返回给客户端,你可以做这个简单的解决方案:

from django.forms.models import model_to_dict
from django.http import JsonResponse


movie = Movie.objects.get(pk=1)
return JsonResponse(model_to_dict(movie))

.values()是我需要将模型实例转换为JSON。

.values()文档:https://docs.djangoproject.com/en/3.0/ref/models/querysets/#values

名为项目的模型的示例使用。

注意:我使用的是Django Rest Framework

from django.http import JsonResponse


@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的结果:

{
"id": 47,
"title": "Project Name",
"description": "",
"created_at": "2020-01-21T18:13:49.693Z",
}

所有这些答案与我对框架的期望相比都有点俗气,我认为到目前为止,如果你使用的是rest框架,最简单的方法是:

rep = YourSerializerClass().to_representation(your_instance)
json.dumps(rep)

这将直接使用Serializer,尊重您在其上定义的字段,以及任何关联等等。

这是一个项目,它可以序列化(JSON基础现在)你的模型中的所有数据,并将它们自动放在一个特定的目录,然后它可以在你想要的任何时候反序列化它…我个人用这个脚本序列化了数千条记录,然后将它们全部加载回另一个数据库,而没有丢失任何数据。

任何对开源项目感兴趣的人都可以贡献这个项目,并为其添加更多特性。

serializer_deserializer_model