Django фильтр по списку значений столбцов
Я использую Django 3.2 и Postgres 13.
У меня есть простая модель:
from django.db import models
class Member(models.Model):
user = models.ForeignKey("User", on_delete=models.CASCADE)
group = models.ForeignKey("Group", on_delete=models.CASCADE)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["user", "group"], name="unique_user_group_tuple"
)
]
Важной информацией здесь является UniqueConstraint
, которая также создает уникальный индекс.
Допустим, у меня есть список из (user_id, group_id)
кортежей:
member_tuples = [(1, 1), (2, 1), (2, 4)]
Я хотел бы получить все существующие Member
объекты, соответствующие этим кортежам, при этом используя индекс. В PG я бы написал:
SELECT * from members where (user_id, group_id) in ((1, 1), (2, 1), (2, 4));
Мой вопрос: как получить нечто подобное в Django? Очевидно, что моя главная задача состоит в том, чтобы постоянно обращаться к индексу unique_user_group_tuple
, чтобы избежать последовательного сканирования
На данный момент лучшим решением, которое я нашел, является следующее:
filters = Q()
for user_id, group_id in member_tuples:
filters |= Q(user_id=user_id, group_id=group_id)
existing_members = Member.objects.filter(filters)
что переводится как
SELECT * from members WHERE (issue_id = 1 AND group_id = 1) OR (issue_id = 2 AND group_id = 1) OR (issue_id = 2 AND group_id = 4);
Это также запрашивает индекс, но не создает ожидаемый запрос.
Итак, я пытаюсь достичь двух разных вещей:
- найти способ аннотировать запись, например, вернуть что-то вроде:
SELECT (user_id, group_id) as member_tuple FROM member
- использовать коллекцию записей в предложении
WHERE
:WHERE something IN ((1,1), (2,1) (2,4));