多个模型的通用 API 声明
Generalized API declaration for multiple models
在用Django开发JWT应用的过程中,注意到CRUDAPIView的声明模式,如:
class Create(generics.CreateAPIView):
queryset = <some django model>.objects.all()
serializer_class = serializer # <some serializer class>
class Read(generics.ListAPIView):
queryset = <some django model>.objects.all()
serializer_class = serializer # <some serializer class>
class Update(generics.RetrieveUpdateAPIView):
queryset = <some django model>.objects.all()
serializer_class = serializer # <some serializer class>
class Delete(generics.DestroyAPIView):
queryset = <some django model>.objects.all()
serializer_class = serializer # <some serializer class>
考虑到我的具体项目有 7 个模型必须具备这些功能,而不是声明上述 class 的 28 个版本,我认为如果有一个 class 如:
class Create(generics.CreateAPIView):
def __init__(self, model, serializer):
self.queryset = model.objects.all()
self.serializer_class = serializer
super().__init__()
class Read(generics.ListAPIView):
def __init__(self, model, serializer):
self.queryset = model.objects.all()
self.serializer_class = serializer
super().__init__()
class Update(generics.RetrieveUpdateAPIView):
def __init__(self, model, serializer):
self.queryset = model.objects.all()
self.serializer_class = serializer
super().__init__()
class Delete(generics.DestroyAPIView):
def __init__(self, model, serializer):
self.queryset = model.objects.all()
self.serializer_class = serializer
super().__init__()
class CRUD:
"""Base class for CRUD Operations"""
def __init__(self, model, serializer):
self.create = Create(model, serializer)
self.read = Read(model, serializer)
self.update = Update(model, serializer)
self.delete = Delete(model, serializer)
接下来是那些 instaciations:
Reg_API = CRUD(Registry, RegistrySerializer)
Tag_API = CRUD(Tag, TagSerializer)
# etc
如果我在 python manage.py shell
上进行测试,实例 Reg_API.create.queryset
returns 正是我所需要的。但是如果我 运行 python manage.py runserver
并尝试访问路由,我会得到 __init__() missing 2 required positional arguments: 'model' and 'serializer'
...
在 urls.py 我的路线定义为:
from .crud import Reg_API
urlpatterns = [
path('api/registry/create', Reg_API.create.as_view())
]
所以我想知道这里缺少什么。我忘记了什么,或者出于某种原因我应该遵循 28 条声明方式?
您正在尝试重新设计一项已有的功能。您想要实现的目标已经存在于 DRF 中并称为 viewset。对于您的情况,此代码足以用于整个注册表 CRUD API:
from rest_framework import viewsets
class RegistryViewSet(viewsets.ModelViewSet):
queryset = Registry.objects.all()
serializer_class = RegistrySerializer
然后在你的 urls.py:
from myapp.views import RegistryViewSet
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'registry', RegistryViewSet, basename='registry')
urlpatterns = router.urls
在用Django开发JWT应用的过程中,注意到CRUDAPIView的声明模式,如:
class Create(generics.CreateAPIView):
queryset = <some django model>.objects.all()
serializer_class = serializer # <some serializer class>
class Read(generics.ListAPIView):
queryset = <some django model>.objects.all()
serializer_class = serializer # <some serializer class>
class Update(generics.RetrieveUpdateAPIView):
queryset = <some django model>.objects.all()
serializer_class = serializer # <some serializer class>
class Delete(generics.DestroyAPIView):
queryset = <some django model>.objects.all()
serializer_class = serializer # <some serializer class>
考虑到我的具体项目有 7 个模型必须具备这些功能,而不是声明上述 class 的 28 个版本,我认为如果有一个 class 如:
class Create(generics.CreateAPIView):
def __init__(self, model, serializer):
self.queryset = model.objects.all()
self.serializer_class = serializer
super().__init__()
class Read(generics.ListAPIView):
def __init__(self, model, serializer):
self.queryset = model.objects.all()
self.serializer_class = serializer
super().__init__()
class Update(generics.RetrieveUpdateAPIView):
def __init__(self, model, serializer):
self.queryset = model.objects.all()
self.serializer_class = serializer
super().__init__()
class Delete(generics.DestroyAPIView):
def __init__(self, model, serializer):
self.queryset = model.objects.all()
self.serializer_class = serializer
super().__init__()
class CRUD:
"""Base class for CRUD Operations"""
def __init__(self, model, serializer):
self.create = Create(model, serializer)
self.read = Read(model, serializer)
self.update = Update(model, serializer)
self.delete = Delete(model, serializer)
接下来是那些 instaciations:
Reg_API = CRUD(Registry, RegistrySerializer)
Tag_API = CRUD(Tag, TagSerializer)
# etc
如果我在 python manage.py shell
上进行测试,实例 Reg_API.create.queryset
returns 正是我所需要的。但是如果我 运行 python manage.py runserver
并尝试访问路由,我会得到 __init__() missing 2 required positional arguments: 'model' and 'serializer'
...
在 urls.py 我的路线定义为:
from .crud import Reg_API
urlpatterns = [
path('api/registry/create', Reg_API.create.as_view())
]
所以我想知道这里缺少什么。我忘记了什么,或者出于某种原因我应该遵循 28 条声明方式?
您正在尝试重新设计一项已有的功能。您想要实现的目标已经存在于 DRF 中并称为 viewset。对于您的情况,此代码足以用于整个注册表 CRUD API:
from rest_framework import viewsets
class RegistryViewSet(viewsets.ModelViewSet):
queryset = Registry.objects.all()
serializer_class = RegistrySerializer
然后在你的 urls.py:
from myapp.views import RegistryViewSet
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'registry', RegistryViewSet, basename='registry')
urlpatterns = router.urls