clean drf-spectacular decorator

x·2024년 4월 13일
0

drf-spectacular

목록 보기
1/2

drf-spectacular는 django에서 문서 작성할 때 유용하다. 시리얼라이저를 사용해서 요청, 응답에 대한 문서를 작성할 수 있고 문서에서 보여 줄 예시, 기본 값도 설정할 수 있다.

데코레이터를 사용해야해서 문서를 작성하다보면 view 메서드보다 데코레이터가 더 커지면서 배보다 배꼽이 더 커지는 경우가 생긴다.

데코레이터를 다른 파일로 이동시켜서 간소화하자.

수정 전 view 메서드에 달려 있는 장황한 데코레이터.

class GetRealEstatesOnSearchView(ListAPIView):
    @extend_schema(
        summary="keyword로 부동산 조회",
        description="keyword로 부동산 조회",
        parameters=[
            OpenApiParameter(
                name="deal_type",
                type=str,
                location=OpenApiParameter.PATH,
                description="deal, jeonse, monthly_rent",
                required=True,
                examples=[
                    OpenApiExample(
                        name="매매",
                        description="매매 타입",
                        value="deal",
                    ),
                    OpenApiExample(
                        name="전세",
                        description="전세 타입",
                        value="jeonse",
                    ),
                    OpenApiExample(
                        name="월세",
                        description="월세 타입",
                        value="monthly_rent",
                    ),
                ],
            ),
            OpenApiParameter(
                name="keyword",
                type=str,
                location=OpenApiParameter.QUERY,
                description="검색어",
                required=True,
                examples=[
                    OpenApiExample(
                        name="강남",
                        description="강남",
                        value="강남",
                    ),
                    OpenApiExample(
                        name="하안미리",
                        description="하안미리",
                        value="하안미리",
                    ),
                    OpenApiExample(
                        name="부산",
                        description="부산",
                        value="부산",
                    ),
                ],
            ),
            OpenApiParameter(
                name="limit",
                type=int,
                location=OpenApiParameter.QUERY,
                description="몇 개 보여줄 지 결정, regions는 3개로 고정",
                required=False,
                default=10,
                examples=[
                    OpenApiExample(
                        name="최소 limit",
                        description="최소 limit",
                        value="10",
                    ),
                    OpenApiExample(
                        name="최대 limit",
                        description="최대 limit",
                        value="30",
                    ),
                ],
            ),
        ],
        request=GetRealEstatesOnSearchRequestSerializer,
        responses={
            200: PolymorphicProxySerializer(
                component_name="RealEstatesAndRegions",
                serializers=[GetRealEstatesAndRegionsOnSearchResponseSerializer],
                resource_type_field_name=None,
            ),
            400: OpenApiResponse(description="bad request"),
            404: OpenApiResponse(description="not found"),
        },
    )
    # @jwt_authenticator
    def get(
        self,
        request: Request,
        *args,
        **kwargs,
    ) -> JsonResponse:
    	pass

schema 파일을 따로 만들어서 데코레이터를 추출한다.
real_estate_view_schema.py

from drf_spectacular.utils import (
    extend_schema,
    OpenApiResponse,
    OpenApiParameter,
    PolymorphicProxySerializer,
    OpenApiExample,
)

from real_estate.serializers import (
    GetRealEstatesAndRegionsOnSearchResponseSerializer,
    GetRealEstatesOnSearchRequestSerializer,
)

def get_real_estates_on_search_view_get_decorator(view_function):
    decorated_view_function = extend_schema(
        summary="keyword로 부동산 조회",
        description="keyword로 부동산 조회",
        parameters=[
            OpenApiParameter(
                name="deal_type",
                type=str,
                location=OpenApiParameter.PATH,
                description="deal, jeonse, monthly_rent",
                required=True,
                examples=[
                    OpenApiExample(
                        name="매매",
                        description="매매 타입",
                        value="deal",
                    ),
                    OpenApiExample(
                        name="전세",
                        description="전세 타입",
                        value="jeonse",
                    ),
                    OpenApiExample(
                        name="월세",
                        description="월세 타입",
                        value="monthly_rent",
                    ),
                ],
            ),
            OpenApiParameter(
                name="keyword",
                type=str,
                location=OpenApiParameter.QUERY,
                description="검색어",
                required=True,
                examples=[
                    OpenApiExample(
                        name="강남",
                        description="강남",
                        value="강남",
                    ),
                    OpenApiExample(
                        name="하안미리",
                        description="하안미리",
                        value="하안미리",
                    ),
                    OpenApiExample(
                        name="부산",
                        description="부산",
                        value="부산",
                    ),
                ],
            ),
            OpenApiParameter(
                name="limit",
                type=int,
                location=OpenApiParameter.QUERY,
                description="몇 개 보여줄 지 결정, regions는 3개로 고정",
                required=False,
                default=10,
                examples=[
                    OpenApiExample(
                        name="최소 limit",
                        description="최소 limit",
                        value="10",
                    ),
                    OpenApiExample(
                        name="최대 limit",
                        description="최대 limit",
                        value="30",
                    ),
                ],
            ),
        ],
        request=GetRealEstatesOnSearchRequestSerializer,
        responses={
            200: PolymorphicProxySerializer(
                component_name="RealEstatesAndRegions",
                serializers=[GetRealEstatesAndRegionsOnSearchResponseSerializer],
                resource_type_field_name=None,
            ),
            400: OpenApiResponse(description="bad request"),
            404: OpenApiResponse(description="not found"),
        },
    )(view_function)

    return decorated_view_function

@get_real_estates_on_search_view_get_decorator만 남아서 깔끔해졌다.

from real_estate.views.schema.real_estate_view_schema import (
    get_real_estates_on_search_view_get_decorator,
)


class GetRealEstatesOnSearchView(ListAPIView):
    @get_real_estates_on_search_view_get_decorator
    def get(
        self,
        request: Request,
        *args,
        **kwargs,
    ) -> JsonResponse:
    pass

0개의 댓글