Django запрос ManyToManyField эквивалентен списку - PullRequest
0 голосов
/ 30 марта 2020

У меня есть список объектов, и модель включает ManyToManyField этого объекта. Я хотел бы получить объекты, которые имеют одинаковый список объектов в этом поле. это означает, что __in не будет работать, потому что он будет делать OR между объектами в списке, а не AND. Я пытался использовать AND Q Lookup, но это не сработало (после проверки текста .query кажется, что он делал AND внутри объекта поля, а не самого объекта, поэтому очевидно, что идентификатор объекта поля не у меня два разных идентификатора для каждого пользователя, но, конечно, я бы хотел сделать один запрос вместо запросов по номерам моего ввода.

Ответы [ 2 ]

1 голос
/ 31 марта 2020

Вам необходимо JOIN целевую таблицу (User в вашем случае) несколько раз (для каждого отдельного пользователя), чтобы построить такой запрос.

Чтобы сделать это в Django, нужно позвонить .filter несколько раз.

users = [user1, user2] # a list of users your are interested to filter on
initial_qs = Results.objects.all() # or whatever your results_query_set is
result_qs = reduce(lambda qs, user: qs.filter(users=user.id), users, initial_qs)

# At this point you will have results containing user1 and user2
# but this also includes results with more users (e.g. users 1, 2 and 3)
# if you want to exclude those, you need to filter by the total users count too
result_qs = result_qs.annotate(cnt=models.Count('users')).filter(cnt=len(users))
0 голосов
/ 30 марта 2020

Я не пробовал это, но я думаю, что вы можете использовать функцию postgresql array_agg. Реализация Django здесь .

from django.contrib.postgres.aggregates import ArrayAgg

ideal_user_list = [] # some list. 
                     # Or fetch it directly from the db using the below query and `get`
Results.objects.annotate(
    related_user_array=ArrayAgg('users__id', ordering='users__id')
).filter(related_user_array=ideal_user_list)
...