@@ -146,7 +146,8 @@ def action(methods=None, detail=None, name=None, url_path=None, url_name=None, *
146
146
)
147
147
148
148
def decorator (func ):
149
- func .bind_to_methods = methods
149
+ func .mapping = MethodMapper (func , methods )
150
+
150
151
func .detail = detail
151
152
func .name = name if name else pretty_name (func .__name__ )
152
153
func .url_path = url_path if url_path else func .__name__
@@ -156,10 +157,70 @@ def decorator(func):
156
157
'name' : func .name ,
157
158
'description' : func .__doc__ or None
158
159
})
160
+
159
161
return func
160
162
return decorator
161
163
162
164
165
+ class MethodMapper (dict ):
166
+ """
167
+ Enables mapping HTTP methods to different ViewSet methods for a single,
168
+ logical action.
169
+
170
+ Example usage:
171
+
172
+ class MyViewSet(ViewSet):
173
+
174
+ @action(detail=False)
175
+ def example(self, request, **kwargs):
176
+ ...
177
+
178
+ @example.mapping.post
179
+ def create_example(self, request, **kwargs):
180
+ ...
181
+ """
182
+
183
+ def __init__ (self , action , methods ):
184
+ self .action = action
185
+ for method in methods :
186
+ self [method ] = self .action .__name__
187
+
188
+ def _map (self , method , func ):
189
+ assert method not in self , (
190
+ "Method '%s' has already been mapped to '.%s'." % (method , self [method ]))
191
+ assert func .__name__ != self .action .__name__ , (
192
+ "Method mapping does not behave like the property decorator. You "
193
+ "cannot use the same method name for each mapping declaration." )
194
+
195
+ self [method ] = func .__name__
196
+
197
+ return func
198
+
199
+ def get (self , func ):
200
+ return self ._map ('get' , func )
201
+
202
+ def post (self , func ):
203
+ return self ._map ('post' , func )
204
+
205
+ def put (self , func ):
206
+ return self ._map ('put' , func )
207
+
208
+ def patch (self , func ):
209
+ return self ._map ('patch' , func )
210
+
211
+ def delete (self , func ):
212
+ return self ._map ('delete' , func )
213
+
214
+ def head (self , func ):
215
+ return self ._map ('head' , func )
216
+
217
+ def options (self , func ):
218
+ return self ._map ('options' , func )
219
+
220
+ def trace (self , func ):
221
+ return self ._map ('trace' , func )
222
+
223
+
163
224
def detail_route (methods = None , ** kwargs ):
164
225
"""
165
226
Used to mark a method on a ViewSet that should be routed for detail requests.
0 commit comments