如何将Django模型对象及其所有字段转换为字典?理想情况下,所有内容都包含带有的外键和字段editable=False
。
让我详细说明。假设我有一个类似以下的Django模型:
from django.db import models
class OtherModel(models.Model): pass
class SomeModel(models.Model):
normal_value = models.IntegerField()
readonly_value = models.IntegerField(editable=False)
auto_now_add = models.DateTimeField(auto_now_add=True)
foreign_key = models.ForeignKey(OtherModel, related_name="ref1")
many_to_many = models.ManyToManyField(OtherModel, related_name="ref2")
在终端中,我已执行以下操作:
other_model = OtherModel()
other_model.save()
instance = SomeModel()
instance.normal_value = 1
instance.readonly_value = 2
instance.foreign_key = other_model
instance.save()
instance.many_to_many.add(other_model)
instance.save()
我想将其转换为以下字典:
{'auto_now_add': datetime.datetime(2015, 3, 16, 21, 34, 14, 926738, tzinfo=<UTC>),
'foreign_key': 1,
'id': 1,
'many_to_many': [1],
'normal_value': 1,
'readonly_value': 2}
有多种方法可以将实例转换为字典,并具有不同程度的转角案例处理和接近所需结果的程度。
1。 instance.dict
instance.__dict__
哪个返回
{'_foreign_key_cache': <OtherModel: OtherModel object>,
'_state': <django.db.models.base.ModelState at 0x7ff0993f6908>,
'auto_now_add': datetime.datetime(2018, 12, 20, 21, 34, 29, 494827, tzinfo=<UTC>),
'foreign_key_id': 2,
'id': 1,
'normal_value': 1,
'readonly_value': 2}
到目前为止,这是最简单的方法,但是缺少many_to_many
,foreign_key
被错误命名,并且其中有两个多余的多余内容。
2。 model_to_dict
from django.forms.models import model_to_dict
model_to_dict(instance)
哪个返回
{'foreign_key': 2,
'id': 1,
'many_to_many': [<OtherModel: OtherModel object>],
'normal_value': 1}
这是唯一的many_to_many
,但缺少不可编辑的字段。
3。 model_to_dict(…, fields=…)
from django.forms.models import model_to_dict
model_to_dict(instance, fields=[field.name for field in instance._meta.fields])
哪个返回
{'foreign_key': 2, 'id': 1, 'normal_value': 1}
这绝对比标准model_to_dict
调用差。
4。 query_set.values()
SomeModel.objects.filter(id=instance.id).values()[0]
哪个返回
{'auto_now_add': datetime.datetime(2018, 12, 20, 21, 34, 29, 494827, tzinfo=<UTC>),
'foreign_key_id': 2,
'id': 1,
'normal_value': 1,
'readonly_value': 2}
这与输出相同,instance.__dict__
但没有额外的字段。 foreign_key_id
仍然是错误的,many_to_many
仍然失踪。
5.自定义功能
django的代码model_to_dict
具有大部分答案。它显式删除了不可编辑的字段,因此,删除该检查并获取多对多字段的外键ID会导致以下代码按预期运行:
from itertools import chain
def to_dict(instance):
opts = instance._meta
data = {}
for f in chain(opts.concrete_fields, opts.private_fields):
data[f.name] = f.value_from_object(instance)
for f in opts.many_to_many:
data[f.name] = [i.id for i in f.value_from_object(instance)]
return data
虽然这是最复杂的选项,但调用to_dict(instance)
会给我们确切的预期结果:
{'auto_now_add': datetime.datetime(2018, 12, 20, 21, 34, 29, 494827, tzinfo=<UTC>),
'foreign_key': 2,
'id': 1,
'many_to_many': [2],
'normal_value': 1,
'readonly_value': 2}
6.使用序列化器
Django Rest Framework的ModelSerialzer
允许你从模型自动构建序列化器。
from rest_framework import serializers
class SomeModelSerializer(serializers.ModelSerializer):
class Meta:
model = SomeModel
fields = "__all__"
SomeModelSerializer(instance).data
returns
{'auto_now_add': '2018-12-20T21:34:29.494827Z',
'foreign_key': 2,
'id': 1,
'many_to_many': [2],
'normal_value': 1,
'readonly_value': 2}
这几乎与自定义函数一样好,但是auto_now_add
是字符串而不是datetime
对象。
奖金回合:更好的模型打印
如果你想要具有更好的python命令行显示的Django模型,请让你的模型将以下子类设置为子类:
from django.db import models
from itertools import chain
class PrintableModel(models.Model):
def __repr__(self):
return str(self.to_dict())
def to_dict(instance):
opts = instance._meta
data = {}
for f in chain(opts.concrete_fields, opts.private_fields):
data[f.name] = f.value_from_object(instance)
for f in opts.many_to_many:
data[f.name] = [i.id for i in f.value_from_object(instance)]
return data
class Meta:
abstract = True
因此,例如,如果我们这样定义模型:
class OtherModel(PrintableModel): pass
class SomeModel(PrintableModel):
normal_value = models.IntegerField()
readonly_value = models.IntegerField(editable=False)
auto_now_add = models.DateTimeField(auto_now_add=True)
foreign_key = models.ForeignKey(OtherModel, related_name="ref1")
many_to_many = models.ManyToManyField(OtherModel, related_name="ref2")
SomeModel.objects.first()
现在调用将产生如下输出:
{'auto_now_add': datetime.datetime(2018, 12, 20, 21, 34, 29, 494827, tzinfo=<UTC>),
'foreign_key': 2,
'id': 1,
'many_to_many': [2],
'normal_value': 1,
'readonly_value': 2}
如何将一个django模型对象转换为一个包含所有字段的判决?所有理想情况下包括外键和字段可编辑=False。 让我详细说明一下。假设我有一个django模型,如下所示: 在终端中,我完成了以下工作: 我想将其转换为以下词典: 回答不满意的问题: Django:将整个模型对象集转换为单个字典 如何将Django模型对象转换为字典,并且仍然保留它们的外键?
问题内容: 如果你是从Google来这里寻找模型的人,请跳过我的问题,然后跳到第一个答案。我的问题只会使你感到困惑。 在Django中,有没有一种很好的方法可以将整个模型对象集合到一个字典中?我的意思是,像这样: …结果是字典,键/值对由模型中的记录组成?还有其他人认为这对他们有用吗? 谢谢。 我只想添加的 更新 是,我的最终目标是能够在模板内进行简单的变量查找。就像是: 结果为DictModel
我是Django的初学者。我需要将模型实例转换为类似于Model.objects的字典。值,与关系字段。所以我写了一个小函数来实现这一点: 所以,我可以这样使用它: 你能提出更好的解决方案吗?谢谢!附言:对不起我的英语。
问题内容: 我正在尝试使用Django中的ValuesQuerySet功能将查询返回的字段数限制为仅需要的字段数。我想将此数据集序列化为JSON对象。但是,Django不断抛出错误。下面包含了我的代码和收到的错误: 错误: 谢谢 ! 问题答案: 尝试使用QuerySet 通过方法对值列表中的字段进行子集设置:
问题内容: 我的模特: 我想同时保存并保存在该模型中: 我知道这是错误的,但是我敢肯定,你会明白我的意思。你会怎么做? 问题答案: 你不能从未保存的对象创建m2m关系。如果有pk,请尝试以下操作: 更新:阅读了saverio的答案后,我决定对这个问题进行更深入的研究。这是我的发现。 这是我最初的建议。它可以工作,但不是最佳选择。(注意:我使用的是和而不是s和,但你明白了。) 它总共产生7个查询:
我正试图通过提供JSON格式的所需请求来使用postman来访问一个服务: 邮递员屏幕 但我得到了一个错误: “无法将类型”java.lang.String“的值转换为所需的类型”SampleRequestObject“;嵌套异常为java.lang.IllegalStateException:无法将类型[java.lang.String]的值转换为所需类型“ 控制器 SampleRequestO