如何将相同的装饰链应用于多个功能
@extend_schema(
methods=['GET'],
responses={(200, STYLES_MIME_TYPE): OpenApiTypes.BINARY})
@extend_schema(
methods=['PUT'],
request={STYLES_MIME_TYPE: OpenApiTypes.BINARY},
responses={(204, 'application/json'): OpenApiResponse(
response={'type': 'array', 'items': {'type': 'integer', 'format': 'int32'}},
examples=[OpenApiExample(
'Returned style IDs example',
status_codes=['204'],
value=[101, 102, 103])])})
@api_view(['GET', 'PUT'])
@permission_classes([IsAuthenticated|ReadOnly])
@renderer_classes([StylesRenderer, StylesJSONRenderer])
@parser_classes([StylesParser])
def styles(request: Request, pid: int) -> Response:
"""
Get or save styles for a project.
GET - protobuf binary response
POST - returnd IDs for saved styles
"""
try:
project = Project.objects.get(pk=pid)
return _handle_styles(request, project)
except Project.DoesNotExist:
raise Http404()
@extend_schema(
methods=['GET'],
responses={(200, STYLES_MIME_TYPE): OpenApiTypes.BINARY})
@extend_schema(
methods=['PUT'],
request={STYLES_MIME_TYPE: OpenApiTypes.BINARY},
responses={(204, 'application/json'): OpenApiResponse(
response={'type': 'array', 'items': {'type': 'integer', 'format': 'int32'}},
examples=[OpenApiExample(
'Returned style IDs example',
status_codes=['204'],
value=[101, 102, 103])])})
@api_view(['GET', 'PUT'])
@permission_classes([IsAuthenticated|ReadOnly])
@renderer_classes([StylesRenderer, StylesJSONRenderer])
@parser_classes([StylesParser])
def styles_xref(request: Request, xref: uuid.UUID) -> Response:
"""
Get or save styles for a project.
GET - protobuf binary response
POST - returnd IDs for saved styles
"""
try:
project = Project.objects.get(xref=xref)
return _handle_styles(request, project)
except Project.DoesNotExist:
raise Http404()
这是django,显然我想为这2个视图使用相同的装饰器。唯一的区别是,一个通过int ID查找对象,另一个通过UUID XREF字段查找对象。我该如何保持干燥?
@extend_schema(
methods=['GET'],
responses={(200, STYLES_MIME_TYPE): OpenApiTypes.BINARY})
@extend_schema(
methods=['PUT'],
request={STYLES_MIME_TYPE: OpenApiTypes.BINARY},
responses={(204, 'application/json'): OpenApiResponse(
response={'type': 'array', 'items': {'type': 'integer', 'format': 'int32'}},
examples=[OpenApiExample(
'Returned style IDs example',
status_codes=['204'],
value=[101, 102, 103])])})
@api_view(['GET', 'PUT'])
@permission_classes([IsAuthenticated|ReadOnly])
@renderer_classes([StylesRenderer, StylesJSONRenderer])
@parser_classes([StylesParser])
def styles(request: Request, pid: int) -> Response:
"""
Get or save styles for a project.
GET - protobuf binary response
POST - returnd IDs for saved styles
"""
try:
project = Project.objects.get(pk=pid)
return _handle_styles(request, project)
except Project.DoesNotExist:
raise Http404()
@extend_schema(
methods=['GET'],
responses={(200, STYLES_MIME_TYPE): OpenApiTypes.BINARY})
@extend_schema(
methods=['PUT'],
request={STYLES_MIME_TYPE: OpenApiTypes.BINARY},
responses={(204, 'application/json'): OpenApiResponse(
response={'type': 'array', 'items': {'type': 'integer', 'format': 'int32'}},
examples=[OpenApiExample(
'Returned style IDs example',
status_codes=['204'],
value=[101, 102, 103])])})
@api_view(['GET', 'PUT'])
@permission_classes([IsAuthenticated|ReadOnly])
@renderer_classes([StylesRenderer, StylesJSONRenderer])
@parser_classes([StylesParser])
def styles_xref(request: Request, xref: uuid.UUID) -> Response:
"""
Get or save styles for a project.
GET - protobuf binary response
POST - returnd IDs for saved styles
"""
try:
project = Project.objects.get(xref=xref)
return _handle_styles(request, project)
except Project.DoesNotExist:
raise Http404()
This is Django, and obviously I want to use the same decorators for those 2 views. The only difference is that one looks up object by int ID, and the other by UUID xref field. How can I keep this DRY?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以定义一个新的装饰器,该装饰符可通过所需的链条返回预装的功能。例如,我们首先可以定义三个自定义装饰器:
这些装饰器目前的调用方式类似于以下内容,这很快就会重复多个功能:
但是,您可以在装饰器正文中装饰包装器功能:
简化功能定义的功能定义。 to:
在您提供的示例中,这可能看起来像以下内容:
使用装饰工厂甚至可以让您快速创建给定的装饰链的不同变体。
You could define a new decorator which returns a pre-decorated function with the chain you want. For example, we can first define three custom decorators:
The way these decorators are presently invoked resembles the following, which quickly becomes repetitive for multiple functions:
However, you can decorate a wrapper function within the body of a decorator:
Which simplifies the function definitions to:
In your provided example, this might look something like the following:
Using a decorator factory could even allow you to quickly create different variants of a given chain of decorators.
修改了 geeksforgeeks
装饰器本质上是普通功能。因此,您可以使用部分方法向他们提供一组参数,而无需实际调用该方法。
现在,我们知道如何将参数预先贴到装饰器上,我们可以尝试将它们链接在一起:
Modified example from GeeksForGeeks
Decorators are, in essence, ordinary functions. Thus, you can use partial method to provide a set of arguments to them without actually calling the method.
Now we know how to pre-apply parameters to a decorator, we can try chaining them: