有多种方法可以将实例转换为字典,并具有不同程度的转角案例处理和接近所需结果的程度。
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_dictmodel_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_dictmodel_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 chaindef 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 serializersclass 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 modelsfrom itertools import chainclass 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): passclass 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}


