My Model:
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')
class Shape(models.Model):
name = CICharField(max_length=300, unique=True)
class Color(models.Model):
name = CICharField(max_length=300, unique=True)
class Symptom(models.Model):
name = CICharField(max_length=300, unique=True)
On the front end, Users can select multiple Symptoms, colors, and Shape to find patterns that will pass to the Pattern
model. I have the following get_queryset on 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_matched=Count('symptoms')
)
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
With this code I can get, queryset with matches symptoms AND tongue_colour AND tongue_shape. But, I want to show queryset with OR/all combinations with what matched.
I am using Django REST API to pass the result data.
class PatternSerializer(serializers.ModelSerializer):
symptoms_matched = serializers.SerializerMethodField()
class Meta:
model = Pattern
fields = ('id', 'name', 'symptoms_matched')
def get_symptoms_matched(self, obj):
return getattr(obj, 'symptoms_matched', None)
For eg: Pattern Data:
Pattern A
symptoms: A, B, C, D
tongue_colour: TC1,TC2,TC5
tongue_shape: TS1,TS3,TS5
Pattern B
symptoms: A, D, P, Q
tongue_colour: TC2,TC3,TC6
tongue_shape: TS1,TS2,TS6
Pattern C
symptoms: A, Q, X, Y
tongue_colour: TC1,TC4,TC7
tongue_shape: TS1,TS4,TS7
For example, if Users select: symptoms: A, Y. tongue_colour: TC1 tongue_shape: TS7
It returns Null. Because there is no exact match. Instead of Null, I want to show users matches with any combination by showing what matched symptoms, color, shape, etc. I want queryset will return all combinations:
Expected Result of above example be like:
3 patterns matched.
[
{
"name": "Pattern A",
"symptoms_matched": 1,
"tongue_color_matched": 1,
"tongue_shape_matched": 0,
},
{
"name": "Pattern B",
"symptoms_matched": 1,
"tongue_color_matched": 0,
"tongue_shape_matched": 0,
},
{
"name": "Pattern C",
"symptoms_matched": 1,
"tongue_color_matched": 0,
"tongue_shape_matched": 1,
},
]
Can anyone tell me how can I achieve this?