[Answered ]-Django ManytoMany Field Queryset for Exact and Similar Match

1๐Ÿ‘

โœ…

A single __in filter will get all diseases that have at least one matching symptom

Then you can annotate the query with the count of matches and then order by this annotation to get the diseases with the most matches first

from django.db.models import Count

Disease.objects.filter(
    symptoms__id__in=query_symptoms
).annotate(
    matches=Count('symptoms')
).order_by('-matches')

The regroup tag can be used to group the results by number of matches in your template

{% regroup diseases by matches as diseases_grouped %}
<ul>
{% for match_count in diseases_grouped %}
    <li>{{ match_count.grouper }} matches
    <ul>
        {% for disease in match_count.list %}
          <li>{{ disease }}</li>
        {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>

Use a SerializerMethodField to add a field to your serializer to access the annotation

class DiseaseSerializer(serializers.ModelSerializer):

    num_matches = serializers.SerializerMethodField()

    class Meta:
        model = Disease
        fields = ('id', 'name', 'symptoms')

    def get_num_matches(self, obj):
        return getattr(obj, 'matches', None)

Leave a comment