如何将一个django模型对象转换为一个包含所有字段的判决?所有理想情况下包括外键和字段可编辑=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}
回答不满意的问题:
Django:将整个模型对象集转换为单个字典
如何将Django模型对象转换为字典,并且仍然保留它们的外键?
只要vars(obj)
,它就可以说明对象的全部值
>>> obj_attrs = vars(obj)
>>> obj_attrs
{'_file_data_cache': <FileData: Data>,
'_state': <django.db.models.base.ModelState at 0x7f5c6733bad0>,
'aggregator_id': 24,
'amount': 5.0,
'biller_id': 23,
'datetime': datetime.datetime(2018, 1, 31, 18, 43, 58, 933277, tzinfo=<UTC>),
'file_data_id': 797719,
}
你也可以加上这个
>>> keys = obj_attrs.keys()
>>> temp = [obj_attrs.pop(key) if key.startswith('_') else None for key in keys]
>>> del temp
>>> obj_attrs
{
'aggregator_id': 24,
'amount': 5.0,
'biller_id': 23,
'datetime': datetime.datetime(2018, 1, 31, 18, 43, 58, 933277, tzinfo=<UTC>),
'file_data_id': 797719,
}
有许多方法可以将实例转换为字典,具有不同程度的角大小写处理和与所需结果的接近程度。
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\u-key
被错误命名,并且它有两个多余的东西。
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
的,但是缺少不可编辑的字段。
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}
这比标准的模型到dict
调用更糟糕。
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}
这与实例的输出相同__dict__
但不包含额外字段<代码>外键id仍然错误,多对多
仍然缺失。
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
虽然这是最复杂的选项,但调用来指定(实例)
可以准确地给出所需的结果:
{'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 Rest框架的ModelSerializer允许您从模型自动构建序列化程序。
from rest_framework import serializers
class SomeModelSerializer(serializers.ModelSerializer):
class Meta:
model = SomeModel
fields = "__all__"
SomeModelSerializer(instance).data
返回
{'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对象。
如果你想要一个django模型有一个更好的python命令行显示,让你的模型子类如下:
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")
调用odel.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模型对象及其所有字段转换为字典?理想情况下,所有内容都包含带有的外键和字段。 让我详细说明。假设我有一个类似以下的Django模型: 在终端中,我已执行以下操作: 我想将其转换为以下字典: 问题答案: 有多种方法可以将实例转换为字典,并具有不同程度的转角案例处理和接近所需结果的程度。 1。 instance.dict 哪个返回 到目前为止,这是最简单的方法,但是缺少,
我是Django的初学者。我需要将模型实例转换为类似于Model.objects的字典。值,与关系字段。所以我写了一个小函数来实现这一点: 所以,我可以这样使用它: 你能提出更好的解决方案吗?谢谢!附言:对不起我的英语。
问题内容: 如果你是从Google来这里寻找模型的人,请跳过我的问题,然后跳到第一个答案。我的问题只会使你感到困惑。 在Django中,有没有一种很好的方法可以将整个模型对象集合到一个字典中?我的意思是,像这样: …结果是字典,键/值对由模型中的记录组成?还有其他人认为这对他们有用吗? 谢谢。 我只想添加的 更新 是,我的最终目标是能够在模板内进行简单的变量查找。就像是: 结果为DictModel
问题内容: 我正在尝试使用Django中的ValuesQuerySet功能将查询返回的字段数限制为仅需要的字段数。我想将此数据集序列化为JSON对象。但是,Django不断抛出错误。下面包含了我的代码和收到的错误: 错误: 谢谢 ! 问题答案: 尝试使用QuerySet 通过方法对值列表中的字段进行子集设置:
首先,我像这样扩展抽象用户: 然后参考如下其他模型: 这是形式: 这是视图: 我的问题是: > < li> 如何显示全名字段 以及如何通过应用程序数据的视图将这些字段保存到MyModel模型中的成员字段中? 更新 我更新了AbstractUser模型,因为我忘记添加first_name
问题内容: 我的模特: 我想同时保存并保存在该模型中: 我知道这是错误的,但是我敢肯定,你会明白我的意思。你会怎么做? 问题答案: 你不能从未保存的对象创建m2m关系。如果有pk,请尝试以下操作: 更新:阅读了saverio的答案后,我决定对这个问题进行更深入的研究。这是我的发现。 这是我最初的建议。它可以工作,但不是最佳选择。(注意:我使用的是和而不是s和,但你明白了。) 它总共产生7个查询: