栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

将Django模型对象转换为所有字段均完整的dict

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

将Django模型对象转换为所有字段均完整的dict

有多种方法可以将实例转换为字典,并具有不同程度的转角案例处理和接近所需结果的程度。

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}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/368724.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号