Django:将整个模型对象集转换为单个字典
Posted
技术标签:
【中文标题】Django:将整个模型对象集转换为单个字典【英文标题】:Django: Converting an entire set of a Model's objects into a single dictionary 【发布时间】:2010-11-10 12:50:27 【问题描述】:如果您从 Google 来这里寻找模型来听写,请跳过我的问题,直接跳到第一个答案。我的问题只会让你困惑。
在 Django 中是否有一种将模型对象的整个集合放入单个字典的好方法?我的意思是,像这样:
class DictModel(models.Model):
key = models.CharField(20)
value = models.CharField(200)
DictModel.objects.all().to_dict()
... 结果是一个字典,其中键/值对由模型中的记录组成?有其他人认为这对他们有用吗?
谢谢。更新 我只想补充一点,我的最终目标是能够在模板中进行简单的变量查找。比如:
DictModel.exampleKey
使用 DictModel.objects.get(key__exact=exampleKey).value 的结果
不过,总体而言,你们的所有回复都非常有帮助,以及处理这些回复的方式有多么不同,这让我感到非常惊讶。非常感谢。 2011 年 10 月更新: 如果你用谷歌搜索“django model_to_dict”,这个问题是最好的结果,这实际上非常糟糕,因为它解决的问题与我所问的不同。 我想要的是能够将查询集中的所有实例映射到以指定模型字段为键的单个字典中。 另一方面,model_to_dict 将单个模型实例转换为字典。 现在,我当时的需求非常具体,而且可能非常罕见(我什至不记得我需要它的项目,或者为什么)。所以我会很惊讶,任何寻找有关 model_to_dict 信息的人都会发现我的问题实际上很有用。对不起。 model_to_dict 似乎是一个比我更常见的用例。 2011 年 12 月更新: 我更改了标题,希望能更好地反映我的初衷。
【问题讨论】:
如果您正在寻找如何将单个 django 模型转换为字典,请到这里:***.com/q/21925671/2800876list_of_json = [model_to_dict(model) for model in list_of_models]
【参考方案1】:
您也可以依赖已经编写好的 django 代码;)。
from django.forms.models import model_to_dict
model_to_dict(instance, fields=[], exclude=[])
【讨论】:
这是一个非常好的解决方案,但我注意到有一个问题。由于此方法是为在表单中使用而编写的,因此它不会转储具有 editable=False 标志的字段。model_to_dict(instance, fields=[field.name for field in instance._meta.fields])
鉴于这个答案的评价很高,我觉得有必要指出 model_to_dict 提供的东西与我最初要求的完全不同。 model_to_dict 将单个模型实例转换为字典,这很棒。我想要的是能够将查询集中的所有实例映射到一个以指定模型字段为键的字典中。
@LarrikJ 从你的问题来看,我无法推断这就是你想要的。此外,使用model_to_dict
可以让您完全实现您所说的最终目标。别忘了,你的问题的标题是“Converting an entire Model into a single dictionary”
model_to_dict(instance, fields=[field.name for field in instance._meta.fields])
不会转储具有editable=False
标志的字段。改用这个:field.name: field.value_from_object(instance) for field in instance._meta.fields
【参考方案2】:
您正在寻找Values member of QuerySet,它允许您从查询中获取字典列表
返回一个 ValuesQuerySet -- 一个 QuerySet 评估为一个列表 字典而不是模型实例 对象。这些字典中的每一个都代表 一个对象,对应的键 到模型的属性名称 对象。
>>> Blog.objects.values()
['id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'],
>>> Blog.objects.values('id', 'name')
['id': 1, 'name': 'Beatles Blog']
【讨论】:
我不认为他想要一个字典列表,他想要一个键是模型键的单个字典.values()
不返回来自 ImageField()
等字段的值。【参考方案3】:
这需要创建一个实际的字典吗?你能只用看起来像字典的东西吗?
class DictModelAdaptor():
def __init__(self, model):
self.model = model
def __getitem__(self, key):
return self.model.objects.get(key=key)
def __setitem__(self, key, item):
pair = self.model()
pair.key = key
pair.value = item
pair.save()
def __contains__(self, key):
...
然后你可以用这种方式包装模型:
modelDict = DictModelAdaptor(DictModel)
modelDict["name"] = "Bob Jones"
等等……
【讨论】:
如果这适用于模板变量查找,这实际上可能是我想要的。你试过这个吗?我还需要几个小时。 是的,我在很多情况下都使用过容器适配器,尽管我当然不想以这种方式使用整个模型。另请注意,此示例有些缩写。您将需要添加一些额外的处理程序和适当的错误处理。 我选择了这个答案,因为它最适合我的具体情况(这比我描述的情况稍微复杂一些)。其他的反应很好,效果也很好。我最喜欢的部分是查找是一次完成的,而不是一次加载整个表。在我看到它之前,我什至没有意识到我想要那个。【参考方案4】:您想要in_bulk
queryset 方法,根据文档:
获取字段值列表 (
id_list
) 和这些值的field_name
,并返回一个字典,将每个值映射到具有给定字段值的对象实例。如果未提供id_list
,则返回查询集中的所有对象。field_name
必须是唯一字段,默认为主键。
它需要一个 ID 列表,因此您需要首先通过 values_list
方法获取它:
ids = MyModel.objects.values_list('id', flat=True)
ids_to_model_instances = MyModel.objects.in_bulk(ids)
# 1: <MyModel: 1>, 2: <MyModel: 2>, 3: <MyModel: 3>
【讨论】:
虽然在这种情况下这对我没有帮助,但它非常简洁,我不知道。谢谢 Django 允许您拥有非整数的主键。如果您的模型以这种方式正确设置,这可能仍然是一个很好的解决方案。 我正在做同样的事情。我得到了 id,但我想要数组中这些 id 的数据。请帮助我【参考方案5】:您可以使用python
serializer:
from django.core import serializers
data = serializers.serialize('python', DictModel.objects.all())
【讨论】:
我还没有尝试过 Django 的序列化程序,所以我无法弄清楚它是如何工作的。我想我需要在交互式会话中尝试这个想法。不过,这似乎是一个解决方案。谢谢。 djangoserializers
可以序列化到queryset
,而model_to_dict
只能序列化到模型实例。【参考方案6】:
使用
dict(((m.key, m.value) for m in DictModel.objects.all())
正如 Tom Leys 所建议的,我们不需要获取整个对象,我们可以只获取我们需要的那些值,例如
dict(((m['key'], m['value']) for m in DictModel.objects.values('key', 'value')))
如果您需要所有值,最好将整个对象保存在 dict 中,例如
dict(((m.key, m) for m in DictModel.objects.all())
【讨论】:
我们应该结合解决方案 - dict(((m['key'], m['value']) for m in DictModel.objects.all().values()) - 这样隐藏的 id 字段未从数据库返回。【参考方案7】:dict((x.name, getattr(o, x.name)) for x in o._meta.fields)
【讨论】:
这与 Luper 的 serialize('python', ...) 解决方案之间的区别之一是,这里的外键字段将表示为实际的相关对象。使用序列化您将只获得相关对象的 id 值,而不是对象本身。【参考方案8】:也许我遗漏了一些东西,但 Django 对象有一个 __dict__
属性,这似乎是你想要的。
【讨论】:
这里似乎找不到。它说[我的模型对象]没有属性'dict' 我认为@ben 的意思是__dict__
。【参考方案9】:
要将模型的值放入字典中,请在需要该字典的位置添加以下代码
from models import DictModel
activity_map = dict(Plan.objects.values_list('key', 'value'))
activity_map 是一个包含所需信息的字典。
【讨论】:
【参考方案10】:user = mymodel.objects.all()
user.values()
你也可以试试
user.values_list() # getting as list
【讨论】:
【参考方案11】:或者你是否试图做类似的事情:
def someview(req):
models = MyModel.objects.all()
toTuple = lambda field: (getattr(field, 'someatt'), getattr(field, 'someotheratt'))
data = dict(map(toTuple,models))
return render_to_response(template, data)
【讨论】:
【参考方案12】:要将查询集中的所有实例映射到单个字典中,并以指定的模型字段作为键,请尝试这样做
from django.forms.models import model_to_dict
from myApp.models import myModel
allObjs = myModel.objects.all()
f = # initialise the output
key = 'key' # one of the fields from myModel
[f.update(x[key]: x) for x in [model_to_dict(y) for y in allObjs]]
return f
【讨论】:
以上是关于Django:将整个模型对象集转换为单个字典的主要内容,如果未能解决你的问题,请参考以下文章