用于完全匹配和相似匹配的 Django ManytoMany 字段查询集
Django ManytoMany Field Queryset for Exact and Similar Match
我有以下型号:
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)
在前端,我有多个 select 框,用户可以在其中 select 多个症状来查找疾病,并将作为 symptoms_selected 参数传递给疾病模型。
我有以下关于疾病的 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
目前,如果用户 select 3 种症状:A、D、Y。它 return 为空。我想向用户展示一些具有 2 和 1 症状的类似匹配项,而不是 Null。
我想要查询集 return:
精确匹配疾病,即 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 标签可用于根据模板中的匹配项数量对结果进行分组
{% 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)
我有以下型号:
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)
在前端,我有多个 select 框,用户可以在其中 select 多个症状来查找疾病,并将作为 symptoms_selected 参数传递给疾病模型。
我有以下关于疾病的 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
目前,如果用户 select 3 种症状:A、D、Y。它 return 为空。我想向用户展示一些具有 2 和 1 症状的类似匹配项,而不是 Null。
我想要查询集 return:
精确匹配疾病,即 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 标签可用于根据模板中的匹配项数量对结果进行分组
{% 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)