带有类数据的Python方法装饰器的问题

问题描述 投票:0回答:1

我正在使用 DRF 和 swagger UI 文档制作一个 API, 我想将基本的 CRUD 操作作为动态视图集类,这样我就可以将类用于另一个模型。 但我有问题。我使用 @swagger_auto_schema 和 @action 作为装饰器。这里的例子 为了我获取所有数据表

#dynamic_crud.py
class DynamicCrud(viewsets.ViewSet):
    
    def __init__(self, serializer_class, model_class, table_name):
        self.serializer_class = serializer_class
        self.model_class = model_class
        self.table_name = table_name

    
    def api_response(self, message, status, data=None):
        return {'message': message, 'status': status, 'data': data}
    
#here is the problem
    @swagger_auto_schema(
        operation_summary=f'Get all {table_name}',
        responses={200: serializer_class(many=True)}
    )
    @action(detail=False, methods=['get'], url_path='getall', url_name=f'{table_name}_getall')
    def get_all(self, request, *args, **kwargs):
        try:
            snippets = self.model_class.objects.filter(is_deleted=0)
            serializer = self.serializer_class(snippets, many=True)
            response_data = self.api_response(f'{self.table_name} retrieved successfully', 'success', serializer.data)
            return Response(response_data, status=status.HTTP_200_OK)
        except Exception as e:
            response_data = self.api_response(str(e), 'error')
            return Response(response_data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

我将装饰器放在类中,装饰器需要引用数据。这个类是父类,数据引用在子类中。

#views.py
table_data = [
    {
        'serializer_class': serializer.TblMCategories_serializer,
        'model_class': models.TblMCategories,
        'table_name': 'category'
    },    
    {
        'serializer_class': serializer.TblMProduct_serializer,
        'model_class': models.TblMProduct,
        'table_name': 'product'
    },
    # {
    #   rest of my table data...
    # }
]

class TblMCategories(dynamic_crud.DynamicCrud):

    def __init__(self):
        self.serializer_class = table_data[0]['serializer_class']
        self.model_class = table_data[0]['model_class']
        self.table_name = table_data[0]['table_name']

我知道我不能在装饰器中使用类自数据,因为它尚未声明或自数据在代码构建期间不可用。有没有什么方法可以将数据作为 self 放入装饰器中,或者使我的装饰器具有所需的引用数据?

python database api oop python-decorators
1个回答
0
投票

您可以创建一个临时装饰器,当使用

swagger_auto_schema
调用方法时,使用
self
动态装饰给定方法,以便
swagger_auto_schema
传递从
self
派生的参数。

改变:

@swagger_auto_schema(
    operation_summary=f'Get all {table_name}',
    responses={200: serializer_class(many=True)}
)

至:

@(lambda method:
    lambda self, *args, **kwargs:
        swagger_auto_schema(
            operation_summary=f'Get all {self.table_name}',
            responses={200: serializer_class(many=True)}
        )(method)(self, *args, **kwargs)
)

这同样适用于

action

改变:

@action(detail=False, methods=['get'], url_path='getall', url_name=f'{table_name}_getall')

至:

@(lambda method:
    lambda self, *args, **kwargs:
        action(
            detail=False,
            methods=['get'],
            url_path='getall',
            url_name=f'{self.table_name}_getall'
        )(method)(self, *args, **kwargs)
)
© www.soinside.com 2019 - 2024. All rights reserved.