DRF 序列化器字段未显示在 Openapi 架构中

Jor*_*Rob 5 django-rest-framework drf-yasg

我使用drf-yasg 包为我的 DRF API设置了 openapi ,但由于某种原因,我的文档中 POST 或 PUT 的所有端点都没有显示所需的必要字段。我如何设置它以显示将数据发送到 API 所需的必要字段,目前它们没有显示在架构中以及为 API 生成的文档中

这是我的代码

#项目级别的urls.py

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from rest_framework import permissions # new
from drf_yasg.views import get_schema_view # new
from drf_yasg import openapi # new


schema_view = get_schema_view( # new
    openapi.Info(
        title="Blog API",
        default_version="v1",
        description="API for CaseMed Insurance",
        terms_of_service="https://www.google.com/policies/terms/",
        contact=openapi.Contact(email="hello@example.com"),
        license=openapi.License(name="BSD License"),
    ),
        public=True,
        permission_classes=(permissions.AllowAny,),
)



urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/auth/', include('user.urls')),
    path("api/services/", include('services.urls')),
    path('swagger/', schema_view.with_ui( # new
    'swagger', cache_timeout=0), name='schema-swagger-ui'),
    path('redoc/', schema_view.with_ui( # new
    'redoc', cache_timeout=0), name='schema-redoc'),

]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Run Code Online (Sandbox Code Playgroud)

序列化器.py

from rest_framework import serializers
from .models import *
from user.serializers import CustomerResponseSerializer


#############################
#### category serializers ###
#############################

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = (
            'name',
            'description'
        )

class CategoryUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = (
            'id',
            'name',
            'description',
            
        )

class CategoryResponseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = (
            'name',
            'description',
            'id',
            'created_by',
            'modified_by'
        )


#############################
#### product serializers ###
#############################


class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = (
            'id',
            'name',
            'category',
            'description',
            'terms_and_conditions',
            'price'
        )

class ProductResponseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = (
            'name',
            'category',
            'description',
            'terms_and_conditions',
            'id'
        )





#######################################
#### Dependant serializers ###
#######################################


class DependantSerializer(serializers.ModelSerializer):
    class Meta:
        model = Dependant
        fields = (
            'first_name',
            'other_names',
            'gender',
            'date_of_birth',
            'relationship'
            
        )


class DependantResponseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Dependant
        fields = (
            'first_name',
            'other_names',
            'gender',
            'date_of_birth',
            'relationship',
            'created_by',
            'modified_by',
            'id'
        )



Run Code Online (Sandbox Code Playgroud)

视图.py


from rest_framework import status
from rest_framework import generics
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import AllowAny, IsAuthenticated

from .serializers import *
from .models import *

# Create your views here.

##########################
##### Category Views #####
##########################



class CreateCategory(APIView):
    serializer_class = CategorySerializer
    permission_classes = (IsAuthenticated,)

    def post(self, request):
        print(request.user)
        serializer = self.serializer_class(data=request.data)
        valid = serializer.is_valid(raise_exception=True)

        if valid:
            new_category = Category(
                name=serializer.data['name'],
                description=serializer.data['description'],
                created_by=request.user
            )

            new_category.save()
            status_code = status.HTTP_201_CREATED

            response = {
                'success': True,
                'statusCode': status_code,
                'message': 'category created successfully!',
                'category': serializer.data
            }

            return Response(response, status=status_code)



class CategoryDetailView(generics.RetrieveAPIView):
    serializer_class = CategoryResponseSerializer
    queryset = Category.objects.all()
    permission_classes = (IsAuthenticated,)


class ListCategory(generics.ListAPIView):
    queryset = Category.objects.all()
    serializer_class = CategoryResponseSerializer
    permission_classes = (IsAuthenticated,)


class UpdateCategory(APIView):
    serializer_class = CategoryUpdateSerializer
    permission_classes = (IsAuthenticated,)

    def put(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        valid = serializer.is_valid(raise_exception=True)

        if valid:
            update_category = Category.objects.get(id=kwargs['pk'])

            
            update_category.name = serializer.data['name']
            update_category.description = serializer.data['description']
            update_category.modified_by = request.user

            update_category.save()
            status_code = status.HTTP_201_CREATED

            response = {
                'success': True,
                'statusCode': status_code,
                'message': 'category updated successfully!',
                'category': serializer.data
            }

            return Response(response, status=status_code)
            


class DeleteCategory(generics.DestroyAPIView):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer
    permission_classes = (IsAuthenticated,)





#########################
##### Product Views #####
#########################


class CreateProduct(APIView):
    serializer_class = ProductSerializer
    permission_classes = (IsAuthenticated,)


    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        valid = serializer.is_valid(raise_exception=True)

        if valid:
            linked_category = Category.objects.get(id=serializer.data['category'])
            new_product = Product(
                name=serializer.data['name'],
                category=linked_category,
                description=serializer.data['description'],
                terms_and_conditions=serializer.data['terms_and_conditions'],
                price=serializer.data['price'],
                created_by=request.user
            )

            new_product.save()
            status_code = status.HTTP_201_CREATED

            response = {
                'success': True,
                'statusCode': status_code,
                'message': 'product created successfully!',
                'product': serializer.data
            }

            return Response(response, status=status_code)


class ProductDetailView(generics.RetrieveAPIView):
    serializer_class = ProductResponseSerializer
    queryset = Product.objects.all()
    permission_classes = (IsAuthenticated,)

class ListProduct(generics.ListAPIView):
    queryset =  Product.objects.all()
    serializer_class = ProductResponseSerializer
    permission_classes = (IsAuthenticated,)

class UpdateProduct(APIView):
    serializer_class = ProductSerializer
    permission_classes = (IsAuthenticated,)

    def put(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        valid = serializer.is_valid(raise_exception=True)

        if valid:
            update_product = Product.objects.get(id=kwargs['pk'])
            linked_category = Category.objects.get(id=serializer.data['category'])
            
            update_product.name = serializer.data['name']
            update_product.category = linked_category
            update_product.description = serializer.data['description']
            update_product.terms_and_conditions = serializer.data['terms_and_conditions']
            update_product.price = serializer.data['price']
            update_product.modified_by = request.user

            update_product.save()
            status_code = status.HTTP_201_CREATED

            response = {
                'success': True,
                'statusCode': status_code,
                'message': 'product updated successfully!',
                'product': serializer.data
            }

            return Response(response, status=status_code)

class DeleteProduct(generics.DestroyAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    permission_classes = (IsAuthenticated,)



Run Code Online (Sandbox Code Playgroud)

生成的 Swagger 文档

生成的 Swagger 文档

小智 1

您可以通过将APIView基类替换为来解决您的问题generics.GenericAPIView

class CreateProduct(generics.GenericAPIView):
    serializer_class = ProductSerializer
    permission_classes = (IsAuthenticated,)
    ...

class UpdateCategory(generics.GenericAPIView):
    serializer_class = CategoryUpdateSerializer
    permission_classes = (IsAuthenticated,)
    ...
Run Code Online (Sandbox Code Playgroud)

这不是 POST 和 PUT http 方法的问题。不显示正确序列化器的视图都是从 APIView 类继承的,不幸的是,它不支持您需要的内省类型。引用文档

注意:组件的自动自省,很多操作参数都依赖于GenericAPIView的相关属性和方法:get_serializer()、pagination_class、filter_backends等。对于基本的APIView子类,默认的自省本质上仅限于此的URL kwarg路径参数原因。