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