【问题标题】:Implement HTTP methods in different APIView class in django在 django 的不同 APIView 类中实现 HTTP 方法
【发布时间】:2022-11-18 20:43:38
【问题描述】:

我有一个带有 2 个路由 some_resource/some_resource/<id> 的 API,我想实现正常的 CRUD 操作(列出、检索、创建、更新、删除)。然而,我不想使用 ViewSet因为我想为每个视图设置 1 个类。因此,为了清楚起见,我需要手动设置路线。 :

class SomeResourceRetrieveView(APIView):
  def get(self, request, pk, *args, **kwargs):
    ...

class SomeResourceListView(APIView):
  def get(self, request, *args, **kwargs):
    ...

class SomeResourceCreateView(APIView):
  def post(self, request, *args, **kwargs):
    ...

所以在 urls.py 中它看起来像这样

url_patterns = [
    path("some_resource/", InvitationTeamAccessListAPI.as_view(), name="some-resource-list"),
    path("some_resource/", InvitationTeamAccessCreateAPI.as_view(), name="some-resource-create"),
    path("some_resource/<int:pk>", InvitationTeamAccessRetrieveAPI.as_view(), name="some-resource-retrieve"),
]

但是,当我在some_resource/ 上使用 POST 时,我得到了 405。我认为 django 在第一个匹配的路由处停止并且没有找到 post 的实现。有没有办法将我所有的视图都插入到相同的模式中,但将它们保留为单独的类?

【问题讨论】:

  • 对不同的视图使用不同的 url,例如:对发布请求使用“some_resource/create”..
  • 我想尽可能保持 API 资源 url 不变,因此不能选择不同的 url

标签: python django django-rest-framework


【解决方案1】:

你可以使用ViewSets

试试这个:

from rest_framework import viewsets
from rest_framework.response import Response

class InvitationTeamAccessViewSet(viewsets.ViewSet):
    """
    Example empty viewset demonstrating the standard
    actions that will be handled by a router class.

    If you're using format suffixes, make sure to also include
    the `format=None` keyword argument for each action.
    """

    def list(self, request):
        # this is your get() method
        queryset = InvitationTeamAccess.objects.all()
        # you should change your serializer name accordingly 
        serializer = InvitationTeamAccessSerializer(queryset, many=True)
        return Response(serializer.data)


    def create(self, request):
        # this is your post method
        # you have to write you post logic here
        pass

    def retrieve(self, request, pk=None):
        # this is your get() details method
        queryset = InvitationTeamAccess.get(pk=pk)
        # you should change your serializer name accordingly 
        serializer = InvitationTeamAccessSerializer(queryset)
        return Response(serializer.data)   

    def update(self, request, pk=None):
        # write your post() method here
        pass

    def partial_update(self, request, pk=None):
        pass

    def destroy(self, request, pk=None):
        pass

在 urls.py 中

from myapp.views import InvitationTeamAccess
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'some_resource/', InvitationTeamAccess, basename='InvitationTeamAccess')
urlpatterns = router.urls

然后使用单个 url 路径,您可以执行多个操作

GET: some_resource/ 将显示 InvitationTeamAccess 的列表
GET: some_resource/1/ 将显示单个 InvitationTeamAccess 的详细信息
POST:some_resource/ 将创建新的 InvitationTeamAccess

还阅读了ModelVieset

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-04
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多