Фильтр Django по нескольким свойствам внешнего ключа

Итак, у меня есть модели Django, которые выглядят следующим образом:

class Test(models.Model):
    cool_prop = models.CharField()

class Metadata(models.Model):
     key = models.CharField()
     value = models.CharField()
     test = models.ForeignKey(Test)

и я хотел бы иметь возможность фильтровать тесты на основе того, содержат ли они пару ключ: значение на основе этих метаданных. По сути, я хотел бы иметь возможность сделать:

tests = Test.objects.all().filter(metadata__key=key and metadata__value=value)

Но я не уверен, как это сделать в Django. Я посмотрел на F и Q заявления. Кажется, что большинство операций Django допускают любые тесты, которые имеют ЛЮБЫЕ метаданные с указанным ключом и ЛЮБЫЕ метаданные с указанным значением. Но мне нужны тесты, в которых 1 метаданные совпадают как по ключу, так и по значению.

2 ответа

Решение

Если вы тестируете только 1 комплект, это просто:

tests = Test.objects.filter(metadata__key=key, metadata__value=value)

Если вы хотите сопоставить несколько пар ключ-значение,

#Assuming that the keyvalue pairs is in a dictionary,
import operator
from django.db.models import Q

k_v_pairs = (Q(metadata__key=key, metadata__value=value) for key, value in k_v_dictionary)
tests = Test.objects.filter(reduce(operator.or_, k_v_pairs)).distinct()

По сути, это эквивалентно тому, чтобы сказать мне: Test которые имеют любую из следующих пар ключ-значение.

Вы можете сделать подзапрос для сопоставления объектов метаданных:

metadata = Metadata.objects.filter(key=key, value=value)
tests = Test.objects.filter(metadata__in=metadata).distinct()
Другие вопросы по тегам