Django Rest Framework Viewset Filter By Value

Допустим, у меня есть набор представлений DRF следующего вида

    class SecretViewset(
        viewsets.ModelViewSet,
    ):
    
        queryset = Secret.objects.all()
        serializer_class = SecretSerializer
    
        @action(methods=['GET'], detail=True)
        def name(self, request, pk=None):
            secrets = Secret.objects.filter(name__contains=pk)
            return Response(self.get_serializer(secrets, many=True).data)

Я хочу иметь возможность поиска по имени в URL. Таким образом, /api/secrets/name/NAMEHERE/

Однако, поскольку ModelViewset реализует mixins.Retrieve, он возвращает 404, потому что сначала ищет /api/secrets/ID/ и не находит его, поэтому выбрасывает 404.

Как правильно было бы добавить возможность поиска по имени, как описано выше?

в вашем urls.py поставьте /api/secrets/name/NAMEHERE/ перед /api/secrets/ID/

Вы можете сделать это, используя простой APIView и пользовательский url-путь.

Код для представления:

class SecretRetrieveView(rest_framework.views.APIView):
    def get(self, request, *args, **kwargs):
        secrets = Secret.objects.filter(name__contains=kwargs['name'])
        return Response(SecretSerializer(secrets, many=True).data)

Код в конфигурации urls: (Не забудьте импортировать SecretRetrieveView!)

custom_urlpatterns = [
    path('/api/secrets/name/<str:name>/', SecretRetrieveView.as_view(), name='secret-retrieve'),
]

Наконец, убедитесь, что в вашем urls conf перед тем, как вы сделаете

urlpatterns += router.urls

Вы делаете

urlpatterns += custom_urlpatterns
Вернуться на верх