Как можно обрабатывать 2 разных типа аргументов с помощью одного представления в django rest framework?
У меня urls.py
выглядит как показано ниже
urlpatterns = [
path("watch-list/<int:pk>/", views.WatchItemDetail.as_view(), name="watch-detail"),
path("watch-list/<str:slug>/", views.WatchItemDetail.as_view(), name="watch-detail-slug"),
]
Итак, я отправляю 2 различных типа аргументов по одному и тому же пути, один из которых pk
, а другой может быть slug
.
В моем views.py
я пишу 2 get
запроса я знаю, что это не будет работать, так как python не поддерживает оверлодинг методов, поэтому как я могу достичь как ниже логики? Мы можем очистить некоторый код также, потому что я повторяю себя с той же логикой.
class WatchItemDetail(APIView):
def get(self, request, pk):
watch_item = get_object_or_404(WatchItem, pk=pk)
watch_item_serializer = WatchItemSerializer(watch_item)
return Response(watch_item_serializer.data, status=status.HTTP_200_OK)
def get(self, request, slug):
watch_item = get_object_or_404(WatchItem, slug=slug)
watch_item_serializer = WatchItemSerializer(watch_item)
return Response(watch_item_serializer.data, status=status.HTTP_200_OK)
Это будет работать только для поля slug
, потому что предыдущий метод перезаписывается следующим, но я хочу, чтобы работали оба.
Вы можете проверить тип и работать соответствующим образом:
class WatchItemDetail(APIView):
def get(self, request, item):
watch_item = get_object_or_404(WatchItem, pk=item) if isinstance(item, int) else get_object_or_404(WatchItem, slug=item)
watch_item_serializer = WatchItemSerializer(watch_item)
return Response(watch_item_serializer.data, status=status.HTTP_200_OK)
Вы можете просто попробовать следующее:
class WatchItemDetail(APIView):
def get(self, request, value):
watch_item = get_object_or_404(WatchItem, pk=value) if isinstance(value, int) else get_object_or_404(WatchItem, slug=value)
watch_item_serializer = WatchItemSerializer(watch_item)
return Response(watch_item_serializer.data, status=status.HTTP_200_OK)
Другой способ состоит в том, чтобы также захватить оба pk
и slug
kwargs следующим образом:
from django.http import Http404
class WatchItemDetail(APIView):
def get(self, request, pk=None, slug=None, *args, **kwargs):
if pk is None:
watch_item = get_object_or_404(WatchItem, pk=pk)
elif slug is None:
watch_item = get_object_or_404(WatchItem, slug=slug)
else:
raise Http404(f'No {WatchItem._meta.object_name} matches the given query.')
watch_item_serializer = WatchItemSerializer(watch_item)
return Response(watch_item_serializer.data, status=status.HTTP_200_OK)