Фильтр 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()