有很多关于如何序列化模型查询集的文档,但是如何将模型实例的字段序列化为 JSON?
django.core
中的类来执行此操作。有什么特别的理由不使用序列化查询集吗?
您可以轻松地使用列表来包装所需的对象,这就是 django 序列化程序正确序列化它所需的全部内容,例如:
from django.core import serializers
# assuming obj is a model instance
serialized_obj = serializers.serialize('json', [ obj, ])
如果您正在处理模型实例列表,那么您可以做的最好的事情就是使用 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)
而已! :)
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
方法中。
你甚至可以通过这种方式使用 Django 的原生 JsonResponse:
from django.http import JsonResponse
JsonResponse(data, encoder=ExtendedEncoder)
json.dumps
和 json.dump
方法一起使用。这样您就不需要更改应用程序的工作流程,因为您使用自定义对象或在转换为 json 之前添加另一个方法调用。只需在编码器中添加您的转换代码,您就可以开始了。
model_to_dict
的部分,或者您没有正确调用它。
听起来您要问的内容涉及序列化 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)
,你就得到了你想要的。
如果您想将单个模型对象作为 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))
如果您要询问如何从模型中序列化单个对象,并且您知道您只会在查询集中获取一个对象(例如,使用 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?"}}
.values()
是将模型实例转换为 JSON 所需的。
.values() 文档:https://docs.djangoproject.com/en/3.0/ref/models/querysets/#values
使用名为 Project 的模型的示例用法。
注意:我正在使用 Django Rest 框架
@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",
}
我通过向我的模型添加序列化方法解决了这个问题:
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
第三步:
return HttpResponse(json.dumps(result), content_type = "application/json")
使用 python 格式的 Django Serializer,
from django.core import serializers
qs = SomeModel.objects.all()
serialized_obj = serializers.serialize('python', qs)
json和python格式有什么区别?
json
格式将返回结果为 str
而 python
em> 将以 list
或 OrderedDict
形式返回结果
OrderedDict
,而不是 dict
要序列化和反序列化,请使用以下命令:
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
您似乎无法序列化实例,您必须序列化一个对象的 QuerySet。
from django.core import serializers
from models import *
def getUser(request):
return HttpResponse(json(Users.objects.filter(id=88)))
我用完了 django 的 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
这种方式怎么样:
def ins2dic(obj):
SubDic = obj.__dict__
del SubDic['id']
del SubDic['_state']
return SubDic
或排除任何你不想要的东西。
与我对框架的期望相比,所有这些答案都有些笨拙,这是迄今为止我认为最简单的方法,如果您使用的是其余框架:
rep = YourSerializerClass().to_representation(your_instance)
json.dumps(rep)
这直接使用序列化器,尊重您在其上定义的字段,以及任何关联等。
这是一个项目,它可以序列化(现在基于 JSON)模型中的所有数据并自动将它们放入特定目录,然后它可以随时反序列化它......我已经用这个脚本亲自序列化了数千条记录,然后将它们全部加载回另一个数据库,而不会丢失任何数据。
任何对开源项目感兴趣的人都可以贡献这个项目并为其添加更多功能。
[0]
吗?并且不需要在您的列表文字中使用尾随逗号(为了 PEP8 的爱;)。