77methods on viewsets that should be included by routers.
88"""
99import types
10- from functools import update_wrapper
1110
1211from django .forms .utils import pretty_name
1312
@@ -23,8 +22,18 @@ def api_view(http_method_names=None):
2322
2423 def decorator (func ):
2524
26- class WrappedAPIView (APIView ):
27- pass
25+ WrappedAPIView = type (
26+ 'WrappedAPIView' ,
27+ (APIView ,),
28+ {'__doc__' : func .__doc__ }
29+ )
30+
31+ # Note, the above allows us to set the docstring.
32+ # It is the equivalent of:
33+ #
34+ # class WrappedAPIView(APIView):
35+ # pass
36+ # WrappedAPIView.__doc__ = func.doc <--- Not possible to do this
2837
2938 # api_view applied without (method_names)
3039 assert not (isinstance (http_method_names , types .FunctionType )), \
@@ -43,6 +52,9 @@ def handler(self, *args, **kwargs):
4352 for method in http_method_names :
4453 setattr (WrappedAPIView , method .lower (), handler )
4554
55+ WrappedAPIView .__name__ = func .__name__
56+ WrappedAPIView .__module__ = func .__module__
57+
4658 WrappedAPIView .renderer_classes = getattr (func , 'renderer_classes' ,
4759 APIView .renderer_classes )
4860
@@ -61,7 +73,7 @@ def handler(self, *args, **kwargs):
6173 WrappedAPIView .schema = getattr (func , 'schema' ,
6274 APIView .schema )
6375
64- return update_wrapper ( WrappedAPIView .as_view (), func )
76+ return WrappedAPIView .as_view ()
6577
6678 return decorator
6779
0 commit comments