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

时间:2009-04-16 16:47:32

标签: python django json django-models serialization

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

18 个答案:

答案 0 :(得分:211)

您可以轻松地使用列表来包装所需的对象,这就是django序列化程序正确序列化所需的所有内容,例如:

from django.core import serializers

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

答案 1 :(得分:50)

如果您正在处理模型实例列表,那么您可以做的最好就是使用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)

那就是它! :)

答案 2 :(得分:41)

要避免数组包装器,请在返回响应之前将其删除:

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,它看起来像是完美的工具。

答案 3 :(得分:10)

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

答案 4 :(得分:8)

如果您询问如何从模型中序列化单个对象并且知道,那么您只需要在查询集中获取一个对象(例如,使用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?"}}

答案 5 :(得分:5)

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

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

答案 6 :(得分:5)

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

答案 7 :(得分:5)

对此有一个很好的答案,我很惊讶没有提到它。仅需几行,您就可以处理日期,模型以及其他所有内容。

制作一个可以处理模型的自定义编码器:

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)

现在,模型,日期和所有内容都可以序列化,而不必放在数组中或序列化和非序列化。

答案 8 :(得分:4)

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

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

答案 9 :(得分:4)

使用列表,它将解决问题

步骤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")

答案 10 :(得分:2)

使用{strong> python 格式的Django Serializer

from django.core import serializers

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

json python 格式有什么区别?

json 格式将结果返回为 str ,而 {{ 1}} 会以 python list

答案 11 :(得分:1)

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

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 = serializers.deserialize("json", serial).next().object

答案 12 :(得分:1)

与我希望从框架(最简单的方法)相比,所有这些答案都有些棘手,如果您使用其余框架,我认为到目前为止,这是最简单的方法:

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

这会直接使用序列化程序,同时尊重您在序列化程序上定义的字段以及任何关联等。

答案 13 :(得分:1)

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

from django.core import serializers
from models import *

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

我用完了django的svn版本,所以这可能不是早期版本。

答案 14 :(得分:1)

这样怎么样:

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

或排除任何你不想要的东西。

答案 15 :(得分:1)

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

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

我返回我的实例的字典

所以返回类似{'field1':value,“field2”:value,....}

的内容

答案 16 :(得分:0)

如果要将单个模型对象作为 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))

答案 17 :(得分:0)

这是一个项目,可以序列化(现在基于JSON)模型中的所有数据,并自动将它们放到特定目录中,然后可以在需要时反序列化...我已经为此序列化了数千条记录脚本,然后将它们全部加载回另一个数据库,而不会丢失任何数据。

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

serializer_deserializer_model