Django запрашивает объект, только если все поля ManyToMany соответствуют dict - PullRequest
0 голосов
/ 28 февраля 2019

Я пытаюсь создать проверочный тест, в котором пользователь сопоставляется только с programs, для которого он отвечает всем требованиям.Пользовательский ввод - это словарь, например:

user_dict = [{location: CA, gender: male, skill: crafts}]

У programs есть requirements, как показано в следующих моделях:

class Program(models.Model):
    name = models.CharField()
    requirements = models.ManyToManyField("Requirement")
class Requirement(models.Model):
    name = models.CharField()
    status = models.CharField()

Я хотел бы запрос получитьвсе programs, для которых встречаются все связанные с ними requirements.Например, если program с именем camp counselor имеет только следующие 2 требования, связанные с ним:

[{'name': 'location', 'status': 'CA'}, {'name': 'skill', 'status': crafts}]

Он будет получен, поскольку все его requirements соответствуют словарю пользователя.Если бы это было 3-е requirement:

[{'name': 'gender', 'status': 'female'}]

Тогда его бы не восстановили.Однако, если бы эти 3 requirement status были male, они бы соответствовали и были извлечены.

В настоящее время я перебираю каждый program и проверяю, есть ли совпадение, ноЯ чувствую, что должен быть лучший способ выполнить это:

for p in program:
    for r in p.requirements.all():
        if user_dict[r.name] == r.status:
            print "Match"
        else:
            print "No Match"

1 Ответ

0 голосов
/ 28 февраля 2019

Если у вас есть один запрос типа:

user_dict = {'location': 'CA', 'gender': 'male', 'skill': 'crafts'}

Вы можете запросить все программы с запросом:

from django.db.models import Q 

query = Q()
for key, value in user_dict.items():
    query |= Q(**{'requirements__name': key, 'requirements__status': value})    
Program.objects.filter(query)

Если мы обнаружим, запрос выше будет выглядеть так:

Q(requirements__name='location', requirements__status='CA') |
Q(requirements__name='gender', requirements__status='male') |
Q(requirements__name='skill', requirements__status='crafts')

Таким образом, он вернет все программы, имеющие любую из вышеперечисленных Requirements.

...