【问题标题】:How can I filter these Django records?如何过滤这些 Django 记录?
【发布时间】:2010-06-15 19:36:23
【问题描述】:

我有一组 Django 模型如下图所示(反向关系的名称显示在黄色气泡中):


(来源:cbstaff.com

在每个关系中,Person 可能有 0 个或多个项目。

此外,slug 字段(不幸的是)不是唯一的;多个 Person 记录可能具有相同的 slug 字段。这些记录本质上是重复的。

我想获取满足以下条件的所有记录的列表:所有重复记录(即具有相同的 slug)至少有一个 Entry 或至少一个 Audio 或至少一个 @987654329 @或至少一个Article

到目前为止,我有以下查询:

Person.objects.values('slug').annotate(num_records=Count('slug')).filter(num_records__gt=1)

这将所有记录按slug 分组,然后添加一个num_records 属性,说明有多少记录具有该段,但未执行附加过滤(我什至不知道这是否会正常工作,因为,给定一组重复记录,一个可能有,例如,Entry,另一个可能有一个Article)。

简而言之,我想找到所有重复的记录并将它们连同它们的关联模型一起折叠到一个记录中。

使用 Django 执行此操作的最佳方法是什么?

【问题讨论】:

  • +1 用于 Django 颜色中的类图!

标签: django django-models


【解决方案1】:

我会在几个查询中执行此操作。第一个是您拥有的重复项列表:

dupes = [p['slug'] for p in Person.objects.values('slug').annotate(num_records=Count('slug')).filter(num_records__gt=1)]

然后我会遍历这些,并为每个决定保留哪个(做出任意决定 - 选择第一个)。然后,对于所有其他主键,只需更新所有其他对象以指向您选择的主键:

for slug in dupes:
    pks = [p.id for p in Person.objects.filter(slug=slug)]
    for pk in pks[1:]:
        Audio.objects.filter(person=pk).update(person=pks[0])
        Author.objects.filter(person=pk).update(person=pks[0])
        Episode.objects.filter(person=pk).update(person=pks[0])
        Entry.objects.filter(person=pk).update(person=pks[0])

【讨论】:

  • 接受这个作为答案。几天前我解决了这个问题,但最终大致按照您的建议进行。
【解决方案2】:

您是否针对类似“group by”的行为研究了 Django 聚合?

http://docs.djangoproject.com/en/dev/topics/db/aggregation/

【讨论】:

  • 是的;我给出的代码行基本上是对记录进行分组,它只是没有进行所需的过滤。
【解决方案3】:

我不确定链接过滤器能否将您带到您想去的地方,因为会有包含两种或多种类型的工件的 Person 条目,上面有他们的名字。看看之前的 StackOverflow 问题及其答案,我认为这将帮助您以您想要的方式将四个查询组合成一个 QuerySet:

How to combine 2 or more querysets in a Django view?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-09
    • 2013-08-25
    • 2021-07-23
    • 2019-03-10
    • 2020-11-29
    • 2020-02-20
    • 2018-04-26
    相关资源
    最近更新 更多