#python #django
#python #django
Вопрос:
Допустим, у меня есть эти модели (MariaDB):
class MediaSeries(models.Model):
name = models.CharField(max_length=200)
description = models.TextField(blank=True)
class MediaFiles(models.Model):
entryNr = models.IntegerField(default=0, help_text="number of episode")
name = models.CharField(max_length=300)
serie = models.ForeignKey(MediaSeries, null=True,
on_delete=models.SET_DEFAULT)
Медиафайлы могут быть одной записью или частью серии. Когда он является частью серии, он будет иметь уникальный entryNr .
entryNr может начинаться с любого числа, а не только с 1.
Теперь мне нужен метод фильтрации для фильтрации всех записей медиафайлов, которые являются частью серии, но только первой записи.
Например, у меня есть этот необработанный список:
{"entryNr": 0, "name": "test a1", "serie": 0},
{"entryNr": 2, "name": "test b1", "serie": 1},
{"entryNr": 3, "name": "test b2", "serie": 1},
{"entryNr": 4, "name": "test b3", "serie": 1},
{"entryNr": 1, "name": "test c1", "serie": 2},
{"entryNr": 2, "name": "test b1", "serie": 2},
{"entryNr": 5, "name": "test d1", "serie": 3},
{"entryNr": 6, "name": "test d2", "serie": 3},
{"entryNr": 7, "name": "test d3", "serie": 3},
{"entryNr": 0, "name": "test e1", "serie": 0},
{"entryNr": 0, "name": "test f1", "serie": 0}
И результат, который мне нужен, должен быть:
{"entryNr": 2, "name": "test b1", "serie": 1},
{"entryNr": 1, "name": "test c1", "serie": 2},
{"entryNr": 5, "name": "test d1", "serie": 3}
С моим текущим представлением и фильтрующим классом я уже могу фильтровать все, что является частью серии:
class MediaFilesFilter(filters.FilterSet):
serie__isnull = filters.BooleanFilter(field_name='serie_id',
lookup_expr='isnull')
class Meta:
model = MediaFiles
fields = ['id', 'name', 'serie__isnull',]
class MediaFilesViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows media to be viewed.
"""
queryset = MediaFiles.objects.all().order_by('name')
serializer_class = MediaFilesSerializer
filter_backends = (filters.DjangoFilterBackend, OrderingFilter,
SearchFilter)
filterset_class = MediaFilesFilter
Но как я могу отфильтровать все первые записи мультимедиа в серии?
Только в качестве информации: логика дыры, которую мне нужно использовать позже с rest_framework, но я думаю, что здесь это не так актуально.
Ответ №1:
Вам придется использовать raw
метод для такого сложного запроса:
MediaFiles.objects.raw("""
SELECT *
FROM my_project_mediafiles mf
INNER JOIN
(
SELECT serie_id, MIN(entryNr) minEntryNr
FROM my_project_mediafiles
GROUP BY serie_id
) min_tbl
ON min_tbl.serie_id = mf.serie_id
WHERE mf.entryNr = minEntryNr
""")
ПРИМЕЧАНИЕ: я не уверен, каково MediaFiles
имя вашей таблицы, оно должно быть «{project_name}_mediafiles»
Комментарии:
1. Спасибо! Но совместимо ли это с другими фильтрами? Мне нужен общий способ, с помощью которого я мог бы динамично комбинировать этот выбор с другими фильтрами.