@Pythonist

Django Rest Filterset — как фильтровать в т.ч по вложенному сериализатору?

Добрый вечер коллеги! Имею такой код:

serializators.py
class CoinCostsSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('price', 'timestamp',)
        model = CoinCosts
        
class CoinSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('symbol', 'crr', 'costs')
        model = Coins
    costs = CoinCostsSerializer(source='coincosts_set.all', many=True)


views.py

class CoinCostFilterSet(filters.FilterSet):

    class Meta:
        model = Coins
        fields = {
            'symbol': ['exact'],
        }


class CoinCostViewSet(viewsets.ModelViewSet):

    queryset = Coins.objects.all()
    serializer_class = CoinSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_class = CoinCostFilterSet


И набирая адрес /CoinCost/?symbol=ZERO например, я имею фильтрацию от Джанго по данной монете.

Но т.к я вложил в сериализатор CoinSerializer цены и время с сериализатора CoinCostsSerializer, я не могу фильтровать в т.ч по периоду времени. А мне это нужно. А именно, По symbol с модели Coins и по Timestamp с модели CoinCossts.

Чтобы я мог набрать /CoinCost/?symbol=ZERO&timestamp_start=2019-12-14T00:00:00&timestamp_end=2019-12-17T00:00:00 и получить фильтрацию не только по монете Zero но и по данному периоду. Можете помочь? Как должен выглядеть мой код для этой задачи?

Пытался эксперементировать с кодом CoinCostFilterSet, но безуспешно.

Спасибо за помощь! Хороших выходных!
  • Вопрос задан
  • 1805 просмотров
Решения вопроса 1
tumbler
@tumbler Куратор тега Django
бекенд-разработчик на python
class DateTimeGteFilter(Filter):
    def filter(qs, value):
        return qs.prefetch_related(
            Prefetch(
                'coincost_set',
                to_attr='filtered_costs',
                queryset=CoinCost.objects.filter(timestamp__gte=value)
            )
        )

class CoinCostFilterSet(FilterSet):
    timestamp_start = DateTimeGteFilter()
    ...

На простейшем уровне как-то так
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы