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)
๐คIain Shelvington
Source:stackexchange.com