我该如何将Django模型对象转换为字典并保留它们的外键?

34
在我的Django应用程序中,如何将Models中的对象转换为包括Model对象外键引用的字典?
当我尝试这样做时:
from django.forms.models import model_to_dict
model_to_dict(instance, fields=[], exclude=[])

生成的字典仅包含直接的字段。我还想获取与模型对象相关的外键。我该如何做?


2
从技术上讲,那篇帖子是这篇的副本。 - Matt Clark
6个回答

32
obj = get_object_or_404(CustomModel,id=some_id)
my_dict = obj.__dict__

似乎更适合使用该属性,而非用于表单的model_to_dict函数。一个优点是__dict__属性不会排除不可编辑字段。一个缺点是它不包括ManyToManyField类型的字段(由于底层反向关系引起的)。 - Dwight Gunning
1
它将外键渲染为user = user_id,我想在这里使用用户名。怎么做? - A.J.
获取带有select_related的查询集? 像这样: MyModel.objects.select_related('user__username').get(pk=some_integer) - freylis

8
我认为我和你有同样的需求——我想要一个简单明了的对象字典表示。其他回答(在我写这篇文章时)不能满足我的需求,而序列化器虽然对其目的很有用,但会产生我不需要的额外信息和不方便的结构。
尽管这种方法可能有些取巧,但它给了我很好的使用体验:
from django.core import serializers

def obj_to_dict(model_instance):
    serial_obj = serializers.serialize('json', [model_instance])
    obj_as_dict = json.loads(serial_obj)[0]['fields']
    obj_as_dict['pk'] = model_instance.pk
    return obj_as_dict

将django_model_object包装在列表中,然后在解析json后访问item 0是必需的,因为某种原因,序列化程序只能序列化模型对象的可迭代项(奇怪)。如果需要处理任何类型的外键字段,则需要一些额外的工具,如果我最终需要编写它,我可能会回复(除非有人先进行编辑!)。暂时就这样吧。

8

您觉得如何:

model_to_dict(instance, fields=[field.name for field in instance._meta.fields])

通过明确命名所有字段,至少应该给您外键ID(尽管我还没有验证)。

请注意,此函数不会返回带有 editable=False 的字段(因为它是用于表单的)。


0

其他答案对我都不太适用。然而,这个似乎解决了我的问题。

def model_to_dict(instance, include=None, exclude=None):
    fields = instance._meta.concrete_fields
    if include is not None:
        return {f.attname: getattr(instance, f.attname) for f in fields if f.name in include}
    if exclude is not None:
        return {f.attname: getattr(instance, f.attname) for f in fields if f.name not in exclude}
    return {f.attname: getattr(instance, f.attname) for f in fields}

0

我想你可能已经解决了你的问题,但是在寻找类似解决方案时,我找到了一些信息。我希望能够在模板中访问对象及其字段/属性。我正在学习Django。

最终我找到了https://docs.djangoproject.com/en/3.0/ref/class-based-views/generic-display/,它似乎可以将对象实例或对象查询集发送到模板中。然后,您可以像使用model.field那样访问对象,甚至如果它是一个外键字段,也可以使用model.foreignmodel.foreignmodelfield

所以这对我来说非常有用。在构建了许多不同类管理器中的自定义“to-dict”方法之后,这对我很有帮助。但是,您需要阅读有关通用视图以及如何自定义它们以获取您想要的详细信息。

-Matt


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接