@@ -39,6 +39,10 @@ class SchemaGenerator(object):
39
39
'patch' : 'partial_update' ,
40
40
'delete' : 'destroy' ,
41
41
}
42
+ known_actions = (
43
+ 'create' , 'read' , 'retrieve' , 'list' ,
44
+ 'update' , 'partial_update' , 'destroy'
45
+ )
42
46
43
47
def __init__ (self , title = None , url = None , patterns = None , urlconf = None ):
44
48
assert coreapi , '`coreapi` must be installed for schema support.'
@@ -118,7 +122,8 @@ def get_api_endpoints(self, patterns, prefix=''):
118
122
if self .should_include_endpoint (path , callback ):
119
123
for method in self .get_allowed_methods (callback ):
120
124
action = self .get_action (path , method , callback )
121
- endpoint = (path , method , action , callback )
125
+ category = self .get_category (path , method , callback , action )
126
+ endpoint = (path , method , category , action , callback )
122
127
api_endpoints .append (endpoint )
123
128
124
129
elif isinstance (pattern , RegexURLResolver ):
@@ -128,21 +133,7 @@ def get_api_endpoints(self, patterns, prefix=''):
128
133
)
129
134
api_endpoints .extend (nested_endpoints )
130
135
131
- return self .add_categories (api_endpoints )
132
-
133
- def add_categories (self , api_endpoints ):
134
- """
135
- (path, method, action, callback) -> (path, method, category, action, callback)
136
- """
137
- # Determine the top level categories for the schema content,
138
- # based on the URLs of the endpoints. Eg `set(['users', 'organisations'])`
139
- paths = [endpoint [0 ] for endpoint in api_endpoints ]
140
- categories = self .get_categories (paths )
141
-
142
- return [
143
- (path , method , self .get_category (categories , path ), action , callback )
144
- for (path , method , action , callback ) in api_endpoints
145
- ]
136
+ return api_endpoints
146
137
147
138
def get_path (self , path_regex ):
148
139
"""
@@ -181,36 +172,41 @@ def get_allowed_methods(self, callback):
181
172
182
173
def get_action (self , path , method , callback ):
183
174
"""
184
- Return a description action string for the endpoint, eg. 'list'.
175
+ Return a descriptive action string for the endpoint, eg. 'list'.
185
176
"""
186
177
actions = getattr (callback , 'actions' , self .default_mapping )
187
178
return actions [method .lower ()]
188
179
189
- def get_categories (self , paths ):
190
- categories = set ()
191
- split_paths = set ([
192
- tuple (path .split ("{" )[0 ].strip ('/' ).split ('/' ))
193
- for path in paths
194
- ])
195
-
196
- while split_paths :
197
- for split_path in list (split_paths ):
198
- if len (split_path ) == 0 :
199
- split_paths .remove (split_path )
200
- elif len (split_path ) == 1 :
201
- categories .add (split_path [0 ])
202
- split_paths .remove (split_path )
203
- elif split_path [0 ] in categories :
204
- split_paths .remove (split_path )
205
-
206
- return categories
207
-
208
- def get_category (self , categories , path ):
209
- path_components = path .split ("{" )[0 ].strip ('/' ).split ('/' )
210
- for path_component in path_components :
211
- if path_component in categories :
212
- return path_component
213
- return None
180
+ def get_category (self , path , method , callback , action ):
181
+ """
182
+ Return a descriptive category string for the endpoint, eg. 'users'.
183
+
184
+ Examples of category/action pairs that should be generated for various
185
+ endpoints:
186
+
187
+ /users/ [users][list], [users][create]
188
+ /users/{pk}/ [users][read], [users][update], [users][destroy]
189
+ /users/enabled/ [users][enabled] (custom action)
190
+ /users/{pk}/star/ [users][star] (custom action)
191
+ /users/{pk}/groups/ [groups][list], [groups][create]
192
+ /users/{pk}/groups/{pk}/ [groups][read], [groups][update], [groups][destroy]
193
+ """
194
+ path_components = path .strip ('/' ).split ('/' )
195
+ path_components = [
196
+ component for component in path_components
197
+ if '{' not in component
198
+ ]
199
+ if action in self .known_actions :
200
+ # Default action, eg "/users/", "/users/{pk}/"
201
+ idx = - 1
202
+ else :
203
+ # Custom action, eg "/users/{pk}/activate/", "/users/active/"
204
+ idx = - 2
205
+
206
+ try :
207
+ return path_components [idx ]
208
+ except IndexError :
209
+ return None
214
210
215
211
# Methods for generating each individual `Link` instance...
216
212
0 commit comments