具有类似 url_path 的 drf 动作视图未在 drf swagger 上显示
drf action views with similar url_path not showing on drf swagger
我有两个具有相同 url_path('favorite')但处理对象检索和删除方法不同的操作视图。这些动作视图中只有一个被映射并显示在 swagger API(使用 drf-yasg)上。
from django.utils.decorators import method_decorator
from drf_yasg.utils import no_body, swagger_auto_schema
from rest_framework.decorators import action
from rest_framework.mixins import ListModelMixin
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework.status import (HTTP_201_CREATED,
HTTP_204_NO_CONTENT,
HTTP_404_NOT_FOUND,
HTTP_200_OK
)
from rest_framework.viewsets import GenericViewSet
from housery.house.models import House
from utils.drf_params import app_id
from utils.mixins import FilterQueryByHouse
from .serializers import HouseSerializer
@method_decorator(name="list", decorator=swagger_auto_schema(
manual_parameters=[app_id]
))
class HouseViewSet(FilterQueryByHouse, ListModelMixin, GenericViewSet):
queryset = House.objects.filter().prefetch_related(
"opening_hours", "special_opening_hours__opening_hours",
)
serializer_class = HouseSerializer
def get_permissions(self):
if self.action in ["list"]:
return [AllowAny()]
return [IsAuthenticated()]
@action(methods=["get"], detail=True, url_path="favorite", url_name="favorite-read")
def retrieve_favorite(self, request):
"""Retrieve favorite house"""
if request.user.favorite_house_id:
instance = request.user.favorite_house
Response(self.get_serializer(instance=instance).data, status=HTTP_200_OK)
return Response(status=HTTP_404_NOT_FOUND)
@action(methods=["delete"], detail=False, url_path="favorite", url_name="favorite-remove")
def unset_favorite(self, request):
"""Remove favorite house"""
request.user.favorite_house = None
request.user.save()
return Response(status=HTTP_204_NO_CONTENT)
@swagger_auto_schema(request_body=no_body)
@action(methods=["post"], detail=True)
def favorite(self, request, pk):
"""set given house id as favorite house"""
instance = self.get_object()
request.user.favorite_house = instance
request.user.save()
return Response(self.get_serializer(instance=instance).data, status=HTTP_201_CREATED)
我只会得到“获取”(retrieve_favorite) 或“删除”(unset_favorite) 中的一个,但不会同时得到两者。我确信我正在做一些我还不能接受的愚蠢行为,我将不胜感激任何帮助。
也许这样行得通?
...
class HouseViewSet(FilterQueryByHouse, ListModelMixin, GenericViewSet):
queryset = House.objects.filter().prefetch_related(
"opening_hours", "special_opening_hours__opening_hours",
)
serializer_class = HouseSerializer
def get_permissions(self):
if self.action in ["list"]:
return [AllowAny()]
return [IsAuthenticated()]
@action(methods=["get"], detail=True, url_path="favorite", url_name="favorite-detail")
def favorite_detail(self, request, *args, **kwargs):
"""Retrieve favorite house"""
if request.user.favorite_house_id:
instance = request.user.favorite_house
Response(self.get_serializer(instance=instance).data, status=HTTP_200_OK)
return Response(status=HTTP_404_NOT_FOUND)
@favorite_detail.mapping.delete
def unset_favorite(self, request, *args, **kwargs):
"""Remove favorite house"""
request.user.favorite_house = None
request.user.save()
return Response(status=HTTP_204_NO_CONTENT)
@swagger_auto_schema(request_body=no_body)
@action(methods=["post"], detail=True)
def favorite(self, request, pk):
"""set given house id as favorite house"""
instance = self.get_object()
request.user.favorite_house = instance
request.user.save()
return Response(self.get_serializer(instance=instance).data, status=HTTP_201_CREATED)
我认为用于处理收藏夹的新视图集是针对这种情况的更好解决方案 - 它更简洁。
我有两个具有相同 url_path('favorite')但处理对象检索和删除方法不同的操作视图。这些动作视图中只有一个被映射并显示在 swagger API(使用 drf-yasg)上。
from django.utils.decorators import method_decorator
from drf_yasg.utils import no_body, swagger_auto_schema
from rest_framework.decorators import action
from rest_framework.mixins import ListModelMixin
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework.status import (HTTP_201_CREATED,
HTTP_204_NO_CONTENT,
HTTP_404_NOT_FOUND,
HTTP_200_OK
)
from rest_framework.viewsets import GenericViewSet
from housery.house.models import House
from utils.drf_params import app_id
from utils.mixins import FilterQueryByHouse
from .serializers import HouseSerializer
@method_decorator(name="list", decorator=swagger_auto_schema(
manual_parameters=[app_id]
))
class HouseViewSet(FilterQueryByHouse, ListModelMixin, GenericViewSet):
queryset = House.objects.filter().prefetch_related(
"opening_hours", "special_opening_hours__opening_hours",
)
serializer_class = HouseSerializer
def get_permissions(self):
if self.action in ["list"]:
return [AllowAny()]
return [IsAuthenticated()]
@action(methods=["get"], detail=True, url_path="favorite", url_name="favorite-read")
def retrieve_favorite(self, request):
"""Retrieve favorite house"""
if request.user.favorite_house_id:
instance = request.user.favorite_house
Response(self.get_serializer(instance=instance).data, status=HTTP_200_OK)
return Response(status=HTTP_404_NOT_FOUND)
@action(methods=["delete"], detail=False, url_path="favorite", url_name="favorite-remove")
def unset_favorite(self, request):
"""Remove favorite house"""
request.user.favorite_house = None
request.user.save()
return Response(status=HTTP_204_NO_CONTENT)
@swagger_auto_schema(request_body=no_body)
@action(methods=["post"], detail=True)
def favorite(self, request, pk):
"""set given house id as favorite house"""
instance = self.get_object()
request.user.favorite_house = instance
request.user.save()
return Response(self.get_serializer(instance=instance).data, status=HTTP_201_CREATED)
我只会得到“获取”(retrieve_favorite) 或“删除”(unset_favorite) 中的一个,但不会同时得到两者。我确信我正在做一些我还不能接受的愚蠢行为,我将不胜感激任何帮助。
也许这样行得通?
...
class HouseViewSet(FilterQueryByHouse, ListModelMixin, GenericViewSet):
queryset = House.objects.filter().prefetch_related(
"opening_hours", "special_opening_hours__opening_hours",
)
serializer_class = HouseSerializer
def get_permissions(self):
if self.action in ["list"]:
return [AllowAny()]
return [IsAuthenticated()]
@action(methods=["get"], detail=True, url_path="favorite", url_name="favorite-detail")
def favorite_detail(self, request, *args, **kwargs):
"""Retrieve favorite house"""
if request.user.favorite_house_id:
instance = request.user.favorite_house
Response(self.get_serializer(instance=instance).data, status=HTTP_200_OK)
return Response(status=HTTP_404_NOT_FOUND)
@favorite_detail.mapping.delete
def unset_favorite(self, request, *args, **kwargs):
"""Remove favorite house"""
request.user.favorite_house = None
request.user.save()
return Response(status=HTTP_204_NO_CONTENT)
@swagger_auto_schema(request_body=no_body)
@action(methods=["post"], detail=True)
def favorite(self, request, pk):
"""set given house id as favorite house"""
instance = self.get_object()
request.user.favorite_house = instance
request.user.save()
return Response(self.get_serializer(instance=instance).data, status=HTTP_201_CREATED)
我认为用于处理收藏夹的新视图集是针对这种情况的更好解决方案 - 它更简洁。