在 Django Rest Framework 中,我对同一模型有两个单独的视图。我想使用相同的 url 模式来访问这两个视图,并根据所使用的方法区分这两个视图。所以我有类似的东西:
class MyObjectListAPIView(generics.ListAPIView):
pass
class MyObjectCreateAPIView(generics.CreateAPIView):
pass
两种观点显然都有不同的逻辑。两者的 url 模式都是
'myObjects\'
,并且根据所使用的方法(GET
或 POST
),需要引用适当的视图(分别为 MyObjectListAPIView
或 MyObjectCreateAPIView
)。有没有办法实现这一点(不恢复到普通 Django 并失去 DRF 的功能)?
简短回答:
实现此目的的现成方法是使用
ViewSets
,特别是 ModelViewSet
,与默认 ModelSerializer
和 DRF 的内置 DefaultRouter
结合使用。它看起来像下面这样:
# views.py
from rest_framework import viewsets
from myapp.models import MyModel
from myapp.serializers import MyModelSerializer
class MyObjectViewSet(viewsets.ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
#urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import MyObjectViewSet
router = DefaultRouter()
router.register(r'myObjects', MyObjectViewSet)
urlpatterns = [
path('', include(router.urls)),
]
注意,这将实现您想要的(即相同的端点“myObjects/”,具有基于 HTTP 方法的不同逻辑(GET -> List、POST -> Create)——但请注意,它还会做的不仅仅是这个,因为您还将在端点“myObjects//”获得关联的检索/更新/删除功能。
更长的答案:
如果您出于任何特定原因想避免使用
ViewSets
,您只需将 GenericAPIView
与 ListModelMixin
和 CreateModelMixin
一起使用即可。这可能如下所示:
from rest_framework import generics, mixins
from myapp.models import MyModel
from myapp.serializers import MyModelSerializer
class MyObjectListCreateAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
然后只需像平常一样将其注册到您的 URL 文件,它应该完全满足您的约束,而不需要
ViewSet
提供的附加功能。