Python 列出唯一的M2M对象
我有一个Python 列出唯一的M2M对象,python,django,Python,Django,我有一个Person模型,带有manytomytoTags。 我正在尝试获取所有标签组合,并列出唯一拥有这些标签的人 例如: 我想说的是: Tag A: Person 2 Tag B: None Tag C: Person 3 Tag D: None Tags [A, B]: Person 1 Tags [A, C]: None Tags [A, D]: None Tags [B, C]: None Tags [B, D]: None Tags [C, D]: None Tags [A, B,
Person
模型,带有manytomy
toTags
。
我正在尝试获取所有标签组合,并列出唯一拥有这些标签的人
例如:
我想说的是:
Tag A: Person 2
Tag B: None
Tag C: Person 3
Tag D: None
Tags [A, B]: Person 1
Tags [A, C]: None
Tags [A, D]: None
Tags [B, C]: None
Tags [B, D]: None
Tags [C, D]: None
Tags [A, B, C]: Person 4
Tags [A, B, D]: None
(etc.)
使用itertools.compositions
我可以迭代所有标记,如:
for L in range(0, len(tag_list)+1):
for tag_combination in combinations(tag_list, L):
print(Person.objects.filter(tag__name__in=tag_list))
但是上面的问题(在print()
语句中)是,第4个人会在“taga”、“tagb”、“tagc”、“Tag[A,B]”、“Tag[A,C]、“Tag[B,C]”、“Tag[B,D]、“Tag[C,D]”等中弹出,而我只希望这个人被列在“Tags[A,B,C]”下
您知道如何最好地实现这一点吗?您可以直接查询M2M表,并在人员和标记之间建立映射:
from collections import defaultdict
people_to_tags = defaultdict(list)
for tag_id, person_id in Person.tags.through.objects.all().values_list('tag_id', 'person_id'):
people_to_tags[person_id].append(tag_id)
然后,只需反转映射即可:
tags_to_people = defaultdict(list)
for person_id, tags in people_to_tags.items():
tags_to_people[tuple(tags)].append(person_id)
您只需要人数为1的行:
tag_to_person = {tag_id: people[0] for tag_id, people in tags_to_people.items() if len(people) == 1}
tag_to_person = {tag_id: people[0] for tag_id, people in tags_to_people.items() if len(people) == 1}