【问题标题】:How can I turn Django Model objects into a dictionary and still have their foreign keys? [duplicate]如何将 Django 模型对象转换为字典并且仍然拥有它们的外键? [复制]
【发布时间】:2012-09-05 03:23:12
【问题描述】:

在我的 Django 应用程序中,如何将模型中的对象转换为包含模型对象的外键引用的字典?

当我尝试这个时:

from django.forms.models import model_to_dict
model_to_dict(instance, fields=[], exclude=[])

结果字典只有直接字段。我还想获取与模型对象相关的外键。我该怎么做?

【问题讨论】:

  • 技术上该帖子与该帖子重复..

标签: python django django-models


【解决方案1】:
obj = get_object_or_404(CustomModel,id=some_id)
my_dict = obj.__dict__

【讨论】:

  • 使用这个属性似乎比应用用于表单的 model_to_dict 函数更合适。一个优点是 dict 属性不排除不可编辑的字段。一个缺点是它不包含 ManyToManyField 类型的字段(由于我假设的底层反向关系)。
  • 它将前键呈现为 user = user_id,我想要这里的用户名。怎么做?/
  • 获取与选择相关的查询集?像这样:MyModel.objects.select_related('user__username').get(pk=some_integer)
【解决方案2】:

怎么样:

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

通过显式命名所有字段,它至少应该为您提供外键 ID(尽管我尚未验证)。

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

【讨论】:

    【解决方案3】:

    我想我和你有同样的需求——我想要一个对象的简单明了的 dict 表示。发布的其他答案(在我写的时候)不会给我那个,序列化程序虽然对他们的目的很有用,但会产生带有我不想要的额外信息的输出,并且结构不方便。

    虽然无可否认,这给了我很好的里程数:

    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 后访问项目 0,因为出于某种原因,序列化程序只能序列化模型对象的可迭代对象(奇怪)。

    你需要一些额外的工具来处理任何类型的外键字段,如果我最终需要编写它,我可能会回帖(除非其他人先编辑它!)。

    暂时 HTH。

    【讨论】:

      【解决方案4】:

      如果您想使用相关模型,您可能需要查看Django serialization

      【讨论】:

        【解决方案5】:

        其他答案都不适合我。然而,这似乎起到了作用。

        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}
        

        【讨论】:

          【解决方案6】:

          我想您已经为您的案例解决了这个问题,但我在寻找类似解决方案时发现了一些信息。我希望能够在模板中访问对象及其字段/属性。我只是在学习django。

          我最终阅读的是https://docs.djangoproject.com/en/3.0/ref/class-based-views/generic-display/,它似乎能够将对象实例或对象查询集发送到模板。然后您可以访问像model.field 这样的对象,或者即使它是外键字段model.foreignmodel.foreignmodelfield

          所以它对我很有用。这是在我在不同的类管理器中构建了一堆自定义的“to-dict”方法之后。这对我帮助很大。但是您必须阅读通用视图以及如何自定义它们才能真正获得所需的详细信息。

          -马特

          【讨论】:

            猜你喜欢
            • 2020-02-17
            • 1970-01-01
            • 2014-03-22
            • 2018-06-04
            • 2016-10-21
            • 1970-01-01
            • 2010-11-10
            • 2011-03-08
            • 2019-02-01
            相关资源
            最近更新 更多