我有一组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执行此操作的最佳方法是什么?
答案 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聚合?
答案 2 :(得分:0)
我不确定链接过滤器是否会让您到达目的地,因为会有Person条目,其中包含两种或更多类型的工件及其名称。看一下之前的StackOverflow问题及其答案,我认为这将帮助您以您希望的方式将四个查询组合到一个QuerySet中: