Python Django:作为值列表查询的一部分的相关模型值列表

Python Django:作为值列表查询的一部分的相关模型值列表,python,django,django-models,Python,Django,Django Models,我试图弄清楚是否可以设置一个类似于Model.objects.values\u list('id','related\u Model\u id')的查询,并返回类似于[(1L,[2L,6L]),(2L,[1L,]),(3L,[1L,3L,4L,5L]),…]以下是一些细节: class Player(models.Model): positions = models.ForeignKey(Position) ... >>> # players 31, 32,

我试图弄清楚是否可以设置一个类似于
Model.objects.values\u list('id','related\u Model\u id')
的查询,并返回类似于
[(1L,[2L,6L]),(2L,[1L,]),(3L,[1L,3L,4L,5L]),…]
以下是一些细节:

class Player(models.Model):
    positions = models.ForeignKey(Position)
    ...

>>> # players 31, 32, 33 play multiple positions, and I want a result to be
>>> # [(player.id, [a list of position.id for all positions]), ...]

>>> Player.objects.filter(id__in=[31, 32, 33]).values_list('id', 'positions__id')
[(31L, 13L), (31L, 7L), (32L, 13L), (32L, 8L), (33L, 13L), (33L, 7L)]
values\u列表
查询为同一
id
值生成多个元组,两个条目分别为
id=31
id=32
id=33
。当我对特定玩家(
id=31
)进行
values\u list
查询时,我会得到我想要的位置id列表:

>>> p31 = Player.objects.get(id=31)
>>> position_ids = p31.positions.values_list('id', flat=True)
>>> type(position_ids)
<class 'django.db.models.query.ValuesListQuerySet'>
>>> position_ids
[13L, 7L]
>>>
>>> # I want [(31L, [13L, 7L]), (32L, [13L, 8L), (33L, [13L, 7L)]
>>> # Without have to do something like a list comprehension:
>>> # [(p.id, list(p.positions.values_list('id', flat=True))
>>> #     for p in Player.objects.filter(id__in=[31, 32, 33])]
p31=Player.objects.get(id=31) >>>位置id=p31.位置.值列表('id',flat=True) >>>类型(位置标识) >>>位置标识 [13L,7L] >>> >>>#我要[(31L,[13L,7L]),(32L,[13L,8L),(33L,[13L,7L)] >>>#不必做列表理解之类的事情: >>>#[(p.id,list(p.positions.values_list('id',flat=True)) >>>#对于Player.objects.filter中的p(id#u in=[31,32,33])]
毫无疑问,对列表的理解将产生我想要的结果。我希望避免对每个
列表(p.positions.values\u list('id',flat=True))的数据库进行多个单独的查询
强制将
ValuesListQuerySet
解析为实际列表。当然,如果我不强制解析,列表理解结果上的操作似乎会执行一个新的
p.positions.values\u list('id',flat=True)
查询。

是的,我希望也有一些分组查询方法

我最近不得不对高度嵌套的模型做类似的操作,以避免一些破坏性的数据库调用高效地获取我需要的所有值。然后,用纯Python将所有内容拼凑成一个字典。结果效率提高了很多,但当然,定制也有其自身的维护缺点

使用作者/书籍模型,其要点如下:

# models.py
class Author(models.Model):
    name = models.CharField()

class Book(models.Model):
    name = models.CharField()
    authors = models.ManyToManyField(Author)
然后在视图(或我的示例中是shell)中构造可以传递给模板的字典:

>>> authors = Author.objects.prefetch_related('book_set').values('id', 'book')
>>> print authors
    [{'book': 1, 'id': 1}, {'book': 2, 'id': 1}, {'book': 2, 'id': 2}]
>>> author_dict = {}
>>> for a in authors:
    if a['id'] not in author_dict:
        author_dict[a['id']] = set()
    author_dict[a['id']].add(a['book'])
>>> print author_dict
    {1: set([1, 2]), 2: set([2])}
这不是你可能想要的答案,但这是我唯一想到的。我很想知道是否有人用一些本地的Django方法解决了这个问题


希望这能有所帮助!

您的答案反映了我的实际工作内容。我运行的搜索查询太多,对数据库造成了严重影响,因此我正在编写一个模型,该模型保存了运行某些查询的方法及其结果。下一步是了解如何让自定义模型管理器检查查询结果是否已保存或是否已保存t需要运行查询并保存结果。您是否考虑过将词典与模型查询绑定在一起?我没有。通常,当我无法再使用Django的语法(非SQL语句)优化查询时,是时候将web服务器与数据库服务器拆分到不同的机器上了(如果您有资源,这是个好主意)如果可能的话,可以使用更多的硬件或自定义SQL。另外,请注意使用
prefetch_related
,在某些情况下,它可能比
select_related
快得多。此外,忘了提一下,但是Django有一个很棒的DB调试器,名为。您可能已经在使用它了,但我想为其他任何想要使用它的人添加它ps by.最近,我开始不断运行
python manage.py debugsqlshell
,并且同样开始使用
prefetch\u related
select\u related
。感谢这些过滤器的示例使用。我的目标是添加自定义查询以扩展QuerySet API,并让管理器调用自定义QuerySet检查结果已经是您描述的python数据对象。我发现链接QuerySet过滤器非常清晰直观,即使使用python数据对象会使下面的逻辑变得复杂。下面是从代码创建dict的另一种方法:
import defaultdict;author\u dict=default\u dict(set);对于authors中的author:author_dict[author['id']]。添加(author['book'])
,它给出了
defaultdict(,{1:set([1,2]),2:set([2]))
。希望我知道如何用换行符格式化这个评论。