如何过滤这些Django记录?

时间:2010-06-15 19:36:24

标签: django django-models

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

Django models http://mipadi.cbstaff.com/images/misc/people_django.jpg

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

此外,slug字段(遗憾)并非唯一;多个Person记录可能具有相同的段塞字段。基本上这些记录是重复的。

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

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

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

这会按slug对所有记录进行分组,然后添加一个num_records属性,说明有多少记录有该段塞,但是没有执行额外的过滤(我甚至不知道这是否会无论如何,正确地工作,因为,给定一组重复记录,可以有例如Entry和另一个Article

简而言之,我想找到所有重复的记录,并将它们及其相关模型折叠成一个记录。

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

3 个答案:

答案 0 :(得分: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])

答案 1 :(得分:0)

您是否考虑过“分组”行为的Django聚合?

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

答案 2 :(得分:0)

我不确定链接过滤器是否会让您到达目的地,因为会有Person条目,其中包含两种或更多类型的工件及其名称。看一下之前的StackOverflow问题及其答案,我认为这将帮助您以您希望的方式将四个查询组合到一个QuerySet中:

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