Django ManytoMany字段精确和相似匹配查询集



我有以下型号:

class Disease(models.Model):
name = CICharField("Disease Name", max_length=200, unique=True)
symptoms = models.ManyToManyField(Symptom, through='DiseaseSymptom', related_name='diseases')

class Symptom(models.Model):
name = CICharField("Symptom Name", max_length=200, unique=True)

在前端,我有多个选择框,用户可以在其中选择多个症状来查找疾病,并将其作为症状_选定参数传递给疾病模型。

我有以下关于疾病的get_queryset>views.py


def get_queryset(self):
params = self.request.query_params
query_symptoms = self.request.GET.getlist('symptoms_selected')
if query_symptoms:
i = 0
queryset = Disease.objects.all()
while i < (len(query_symptoms)):
symptom = [query_symptoms[i]]
queryset = queryset.filter(symptoms__id__in=symptom)
i=i+1
else:
queryset = Disease.objects.all()
return queryset
serializer_class = DiseaseSerializer

我使用Django REST API来传递结果数据。

class DiseaseSerializer(serializers.ModelSerializer):
class Meta:
model = Disease
fields = ('id', 'name', 'symptoms')

例如:疾病数据:

疾病A:出现症状:A、B、C、D

疾病B:出现症状:A、D、p、Q

疾病C:出现症状:A、Q、X、Y

当前,如果用户选择3个症状:A、D、Y,则返回Null。我想向用户展示一些类似的匹配,而不是Null,它们有2和1的症状。

我希望queryset返回:

完全匹配的疾病,即3种症状匹配的疾病

2症状匹配疾病

1种症状匹配疾病

有人能告诉我怎样才能做到这一点吗?

单个__in过滤器将获得至少有一个匹配症状的所有疾病

然后,您可以用匹配次数对查询进行注释,然后根据此注释排序,以首先获得匹配次数最多的疾病

from django.db.models import Count
Disease.objects.filter(
symptoms__id__in=query_symptoms
).annotate(
matches=Count('symptoms')
).order_by('-matches')

重组标签可用于根据模板中的匹配数量对结果进行分组

{% 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>

使用SerializerMethodField向序列化程序添加一个字段以访问注释

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)

最新更新