Получить набор объектов, в которых поле является отличительным
У меня есть модель, подобная следующей:
class Reports(models.Model):
reportid = models.AutoField(primary_key=True, unique=True)
name = models.CharField(max_length=100)
description = models.CharField(max_length=300, default='', blank=True)
value = models.FloatField(default=0)
Мне нужно выполнить поиск в модели по совпадению поискового термина в поле name. Затем мне нужно вернуть набор запросов, содержащий объекты, каждый из которых имеет уникальные имена, соответствующие поисковому термину.
Смотрите пример:
testsearchterm = 'bs'
initreports = Reports.objects.filter(name__lower__contains=testsearchterm)
print("initreports:", initreports)
Результат:
initreports: <QuerySet [<Reports: FBS>, <Reports: PPBS>, <Reports: FBS>, <Reports: FBS>, <Reports: PPBS>, <Reports: FBS>, <Reports: FBS>, <Reports: PPBS>, <Reports: Random Blood Sugar (RBS)>,
Теперь я получаю отдельные имена
reports = Reports.objects.filter(name__lower__contains=testsearchterm).values_list('name', flat=True).distinct()
print("Unique values:", reports)
Результат:
Unique values: <QuerySet ['FBS', 'PPBS', 'Random Blood Sugar (RBS)', 'Sleep study to r/o Obstructive sleep apnea', 'Serum HBsAg']>
Теперь мне нужен полный набор запросов, а не только имена, чтобы я мог сериализовать результаты и вернуть другие поля тоже.
for name in tests:
res = Reports.objects.filter(name=name).first()
print(res, type(res))
Результаты:
FBS <class 'appointments.models.Reports'>
PPBS <class 'appointments.models.Reports'>
Random Blood Sugar (RBS) <class 'appointments.models.Reports'>
Sleep study to r/o Obstructive sleep apnea <class 'appointments.models.Reports'>
Serum HBsAg <class 'appointments.models.Reports'>
Мне нужен кверисет из вышеперечисленных, например, следующий:
<QuerySet [<Reports: FBS>, <Reports: PPBS>, <Reports: RBS>, <Reports: HBsAg>]
Нужно, чтобы это был правильный queryset, а не список или набор, чтобы я мог использовать DRF modelserializer как есть.
N.B. DISTINCT ON fields is not supported by this database backend(mysql)
Вы фильтруете, чтобы вернуть только имя из следующего набора запросов:
Reports.objects.filter(name__lower__contains=testsearchterm).values_list('name', flat=True).distinct()
Если убрать вызов values_list, то вместо списка строк получится queryset.
Reports.objects.filter(name__lower__contains=testsearchterm).distinct()
Ссылка: https://docs.djangoproject.com/en/4.0/ref/models/querysets/#distinct
Попробуйте это:
unique_names = [Report.objects.filter(name=name)[0].pk for name in Reports.objects.filter(name__lower__contains=testsearchterm).values_list('name', flat=True).distinct()]
query = Report.objects.filter(pk__in=unique_names)