Django queryset с совпадением всех комбинаций
Моя модель:
class Pattern(models.Model):
name = CICharField("Pattern Name", max_length=200, unique=True)
symptoms = models.ManyToManyField(Symptom, through='PatternSymptom', related_name='patterns')
tongue_colour = models.ManyToManyField(Color, verbose_name="Tongue Body Colour", blank=True, related_name='patterns')
tongue_shape = models.ManyToManyField(Shape, verbose_name="Tongue Body Shape", blank=True, related_name='patterns')
tongue_quality = models.ManyToManyField(Quality, verbose_name="Tongue Body Features", blank=True, related_name='patterns')
Цвет, форма, качество модели:
class Color(models.Model):
name = CICharField(max_length=300, unique=True)
На фронт-энде пользователи могут выбрать несколько симптомов, цвет, форму, качество, чтобы найти паттерн, и это будет передано в модель Pattern как symptoms_selected params. У меня есть следующий get_queryset на Pattern > views.py
def get_queryset(self):
params = self.request.query_params
query_symptoms = self.request.GET.getlist('symptoms_selected')
tongue_colour = self.request.GET.get('tongue_colour')
tongue_shape = self.request.GET.get('tongue_shape')
if query_symptoms:
queryset = Pattern.objects.filter(
symptoms__id__in=query_symptoms
).annotate(
symptom_matches=Count('symptoms')
).annotate(
pattern_weight=Sum('pattern_to_symptom__priority')
).annotate(
key_count=Count('pattern_to_symptom__priority')
).order_by('-matches','-pattern_weight','most_common')
else:
queryset = Pattern.objects.all().filter(is_searchable=True)
if tongue_colour is not None and tongue_colour.isnumeric():
queryset = queryset.filter(tongue_colour__id__in=tongue_colour).annotate(tongue_color_matches=Count('tongue_colour'));
if tongue_shape is not None and tongue_shape.isnumeric():
queryset = queryset.filter(tongue_shape__id__exact=tongue_shape).annotate(tongue_shape_matches=Count('tongue_shape'));
return queryset
С помощью этого кода я могу получить кверисет с совпадениями симптомов И цвет_языка И форма_языка. Но я хочу показать кверисет с OR/все комбинации с тем, что совпало.
Например: Данные шаблона:
Паттерн A: Симптомы: A, B, C, D Цвет языка: TC1, TC2, TC5 Форма языка: TS1, TS3, TS5
Шаблон B: Симптомы: A, D, P, Q Цвет языка: TC2, TC3, TC6 Форма языка: TS1, TS2, TS6
Паттерн C: Симптомы: A, Q, X, Y Цвет языка: TC1, TC4, TC7 Форма языка: TS1, TS4, TS7
Например, если Пользователи выбирают: 2 симптома: A, Y. Цвет языка: TC1 Форма языка: TS7
Выдает Null. Потому что нет точного совпадения. Вместо Null я хочу показывать пользователям совпадения с любой комбинацией, показывая, какие были совпадения симптомов, цвета, формы и т.д. Я хочу, чтобы queryset возвращал все комбинации:
Искомый результат приведенного выше примера будет выглядеть так:
3 шаблона совпали.
[
{
"name": "Pattern A",
"symptoms_matches": 1,
"tongue_color_matches": 1,
"tongue_shape_matches": 0,
},
{
"name": "Pattern B",
"symptoms_matches": 1,
"tongue_color_matches": 0,
"tongue_shape_matches": 0,
},
{
"name": "Pattern C",
"symptoms_matches": 1,
"tongue_color_matches": 0,
"tongue_shape_matches": 1,
},
]
Я использую Django REST API для передачи данных результата.
class PatternSerializer(serializers.ModelSerializer):
class Meta:
model = Pattern
fields = ('id', 'name', 'symptoms', 'symptoms_matched')
Подобно симптому matched я хочу передать также tongue_color_matched & tongue_shape_matched. Может ли кто-нибудь сказать мне, как я могу этого добиться?
Вы можете использовать Q-объект для того, чтобы выполнить запрос с помощью OR.
from django.db.models import Q
queryset = Pattern.objects.filter(
Q(symptoms__id__in=symptom) |
Q(tongue_shape__id__exact=tongue_shape) |
Q(tongue_colour__id__in=tongue_colour))