是否可以为每个模型自动创建ViewSet和序列化器?

时间:2019-12-16 13:54:34

标签: python django django-rest-framework

在我们的项目中,我们有大量的模型,其中一些仍在开发中。我想使用Django Rest Framework创建REST API,但不想为我们拥有的每个模型创建单独的序列化器类和ModelViewSet(因为它们中的大多数应该可以通过API访问)。

当前我们的每个模型都有一个类似的序列化器:

class ItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = Item
        fields = '__all__'

此外,在views.py中还有ModelViewSet:

class ItemViewSet(viewsets.ModelViewSet):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer

是否可以以某种方式减少代码量并使此方法更加灵活?我在想这样的事情:

for model in models:
    ser = createSerializer()
    createViewSet(ser)

在每次调用的地方都会创建一个单独的类。还是甚至有一个使这成为可能的课程?

2 个答案:

答案 0 :(得分:0)

您可以为视图创建一个通用类,然后通过extra url paramaters传递模型和任何其他信息。

例如:

class URLModelAPIView(generics.ListAPIView):
    def dispatch(self, request, *args, **kwargs):
        self.model = kwargs.pop('model')
        self.queryset = self.model.objects.all()
        self.serializer = kwargs.pop('serializer')
        return super().dispatch(request, *args, **kwargs)

然后在您的urls.py

from django.urls import path
from . import models, serializers, views

urlpatterns = [
    path(
        'customer/',
        views.URLModelAPIView.as_view(),
        {
            'model': models.Customer,
            'serializer': serializers.CustomerSerializer,
        }
    ),
    path(
        'customer_contact/',
        views.URLModelAPIView.as_view(),
        {
            'model': models.CustomerContact,
            'serializer': serializers.CustomerContactSerializer,
        }
    ),
]

使用路由器时,相同的逻辑适用于视图集。

答案 1 :(得分:0)

在@bdoubleus答案的基础上,我们可以使用上述视图集进行少量修改:

class GenericAPIView(generics.ListAPIView):
    def dispatch(self, request, *args, **kwargs):
        self.model = kwargs.pop('model')
        self.queryset = self.model.objects.all()
        serializer = GeneralSerializer  # Constructor here would throw "'GeneralSerializer' object is not callable"
        serializer.Meta.model = self.model
        self.serializer_class = serializer
        return super().dispatch(request, *args, **kwargs)

第二,我们需要创建一个简单的模板类以在serializers.py中进行序列化:

from rest_framework import serializers

# Template class for serializing
class GeneralSerializer(serializers.ModelSerializer):
    class Meta:
        fields = '__all__'

要结束此生成器,我们需要为urls.py中的每个模型创建一个URL路由:

app = apps.get_app_config('testapp')  # Add own app name

for model_name, model in app.models.items():
    urlpatterns.append(path(model_name, views.GenericAPIView.as_view(), {'model': model}))