16 |
16 |
17 """Helpers functions for displaying views. |
17 """Helpers functions for displaying views. |
18 """ |
18 """ |
19 |
19 |
20 __authors__ = [ |
20 __authors__ = [ |
21 '"Todd Larsen" <tlarsen@google.com>', |
|
22 '"Sverre Rabbelier" <sverer@rabbelier.nl>', |
21 '"Sverre Rabbelier" <sverer@rabbelier.nl>', |
23 '"Pawel Solyga" <pawel.solyga@gmail.com>', |
|
24 ] |
22 ] |
25 |
23 |
26 |
24 |
27 from django import http |
25 from django import http |
28 from django.utils.translation import ugettext_lazy |
26 from django.utils.translation import ugettext_lazy |
31 import soc.logic.out_of_band |
29 import soc.logic.out_of_band |
32 import soc.views.helper.lists |
30 import soc.views.helper.lists |
33 import soc.views.helper.responses |
31 import soc.views.helper.responses |
34 import soc.views.out_of_band |
32 import soc.views.out_of_band |
35 |
33 |
|
34 from soc.logic import dicts |
36 from soc.logic import models |
35 from soc.logic import models |
37 from soc.logic import validate |
36 from soc.logic import validate |
38 from soc.views import simple |
37 from soc.views import simple |
39 from soc.views import helper |
38 from soc.views import helper |
40 from soc.views.helper import access |
39 from soc.views.helper import access |
47 on the the child-classes to define the following fields: |
46 on the the child-classes to define the following fields: |
48 |
47 |
49 self._logic: the logic singleton for this entity |
48 self._logic: the logic singleton for this entity |
50 """ |
49 """ |
51 |
50 |
|
51 DEF_SUBMIT_MSG_PARAM_NAME = 's' |
|
52 |
|
53 DEF_CREATE_NEW_ENTITY_MSG = ugettext_lazy( |
|
54 ' You can create a new %(model_type)s by visiting' |
|
55 ' <a href="%(create)s">Create ' |
|
56 'a New %(Type)s</a> page.') |
|
57 |
52 def __init__(self, params=None, rights=None): |
58 def __init__(self, params=None, rights=None): |
53 """ |
59 """ |
54 |
60 |
55 Args: |
61 Args: |
56 rights: This dictionary should be filled with the access check |
62 rights: This dictionary should be filled with the access check |
57 functions that should be called |
63 functions that should be called, it will be modified in-place. |
58 params: This dictionary should be filled with the parameters |
64 params: This dictionary should be filled with the parameters |
59 specific to this entity. |
65 specific to this entity, required fields are: |
|
66 name: the name of the entity (names should have sentence-style caps) |
|
67 name_short: the short form name of the name ('org' vs 'organization') |
|
68 name_plural: the plural form of the name |
|
69 edit_form: the class of the Django form to be used when editing |
|
70 create_form: the class of the Django form to be used when creating |
|
71 edit_template: the Django template to be used for editing |
|
72 public_template: the Django template to be used as public page |
|
73 list_template: the Django template to be used as list page |
|
74 lists_template: the Django templates to search for the list page |
|
75 delete_redirect: the Django template to redirect to on delete |
|
76 create_redirect: the Django template to redirect to after creation |
|
77 save_message: the message to display when the entity is saved |
|
78 edit_params: the params to use when editing |
60 """ |
79 """ |
61 |
80 |
62 new_rights = {} |
81 new_rights = {} |
63 new_rights['base'] = [access.checkIsLoggedIn] |
82 new_rights['any_access'] = [access.checkIsLoggedIn] |
64 |
83 |
65 self._rights = soc.logic.dicts.mergeDicts(rights, new_rights) |
84 self._rights = dicts.merge(rights, new_rights) |
66 self._params = params |
85 self._params = params |
67 |
|
68 self.DEF_SUBMIT_MSG_PARAM_NAME = 's' |
|
69 |
|
70 self.DEF_CREATE_NEW_ENTITY_MSG = ugettext_lazy( |
|
71 ' You can create a new %(model_type)s by visiting' |
|
72 ' <a href="%(create)s">Create ' |
|
73 'a New %(Type)s</a> page.') |
|
74 |
86 |
75 def public(self, request, page=None, **kwargs): |
87 def public(self, request, page=None, **kwargs): |
76 """Displays the public page for the entity specified by **kwargs |
88 """Displays the public page for the entity specified by **kwargs |
77 |
89 |
78 Args: |
90 Args: |
193 |
205 |
194 def editGet(self, request, entity, context): |
206 def editGet(self, request, entity, context): |
195 """Same as edit, but on GET |
207 """Same as edit, but on GET |
196 """ |
208 """ |
197 #TODO(SRabbelier) Construct a suffix |
209 #TODO(SRabbelier) Construct a suffix |
198 suffix = None |
210 suffix = None |
199 is_self_referrer = helper.requests.isReferrerSelf(request, suffix=suffix) |
|
200 |
211 |
201 # Remove the params from the request, this is relevant only if |
212 # Remove the params from the request, this is relevant only if |
202 # someone bookmarked a POST page. |
213 # someone bookmarked a POST page. |
203 if request.GET.get(self.DEF_SUBMIT_MSG_PARAM_NAME): |
214 is_self_referrer = helper.requests.isReferrerSelf(request, suffix=suffix) |
|
215 if request.GET.get(DEF_SUBMIT_MSG_PARAM_NAME): |
204 if (not entity) or (not is_self_referrer): |
216 if (not entity) or (not is_self_referrer): |
205 return http.HttpResponseRedirect(request.path) |
217 return http.HttpResponseRedirect(request.path) |
206 |
218 |
207 if entity: |
219 if entity: |
208 # Note: no message will be displayed if parameter is not present |
220 # Note: no message will be displayed if parameter is not present |
209 context['notice'] = helper.requests.getSingleIndexedParamValue( |
221 context['notice'] = helper.requests.getSingleIndexedParamValue( |
210 request, |
222 request, DEF_SUBMIT_MSG_PARAM_NAME, |
211 self.DEF_SUBMIT_MSG_PARAM_NAME, |
223 values=self._params['save_message']) |
212 values=self._params['save_message']) |
|
213 |
224 |
214 # populate form with the existing entity |
225 # populate form with the existing entity |
215 form = self._params['edit_form'](instance=entity) |
226 form = self._params['edit_form'](instance=entity) |
216 else: |
227 else: |
217 form = self._params['create_form']() |
228 form = self._params['create_form']() |
219 context['form'] = form |
230 context['form'] = form |
220 context['entity'] = entity |
231 context['entity'] = entity |
221 context['entity_type'] = self._params['name'] |
232 context['entity_type'] = self._params['name'] |
222 context['entity_type_plural'] = self._params['name_plural'] |
233 context['entity_type_plural'] = self._params['name_plural'] |
223 |
234 |
224 template = self._params['create_template'] |
235 template = self._params['edit_template'] |
225 |
236 |
226 return helper.responses.respond(request, template, context) |
237 return helper.responses.respond(request, template, context) |
227 |
238 |
228 def list(self, request, page=None): |
239 def list(self, request, page=None): |
229 """Displays the list page for the entity type |
240 """Displays the list page for the entity type |
296 if not entity: |
307 if not entity: |
297 #TODO: Create a proper error page for this |
308 #TODO: Create a proper error page for this |
298 return http.HttpResponseRedirect('/') |
309 return http.HttpResponseRedirect('/') |
299 |
310 |
300 if not self._logic.isDeletable(entity): |
311 if not self._logic.isDeletable(entity): |
301 # TODO: Direct user to page telling them they can't delete that entity, and why |
312 # TODO: Update the notice area telling the user they can't delete the entity |
302 pass |
313 pass |
303 |
314 |
304 self._logic.delete(entity) |
315 self._logic.delete(entity) |
305 redirect = self._params['delete_redirect'] |
316 redirect = self._params['delete_redirect'] |
306 |
317 |
313 request: The django request object |
324 request: The django request object |
314 entity: the entity to make public |
325 entity: the entity to make public |
315 fields: The new field values |
326 fields: The new field values |
316 """ |
327 """ |
317 |
328 |
318 pass |
329 raise NotImplementedError |
319 |
330 |
320 def checkUnspecified(self, access_type, request): |
331 def checkUnspecified(self, access_type, request): |
321 """Checks whether an unspecified access_type should be allowed |
332 """Checks whether an unspecified access_type should be allowed |
322 |
333 |
323 Args: |
334 Args: |
339 False: If a check failed, in this case self._response will contain |
350 False: If a check failed, in this case self._response will contain |
340 the response provided by the failed access check. |
351 the response provided by the failed access check. |
341 """ |
352 """ |
342 |
353 |
343 if access_type not in self._rights: |
354 if access_type not in self._rights: |
|
355 # No checks defined, so do the 'generic check' and bail out |
344 self.checkUnspecified(access_type, request) |
356 self.checkUnspecified(access_type, request) |
345 return |
357 return |
346 |
358 |
347 # Call each access checker |
359 # Call each access checker |
348 for check in self._rights['base']: |
360 for check in self._rights['any_access']: |
349 check(request) |
361 check(request) |
350 |
362 |
351 for check in self._rights[access_type]: |
363 for check in self._rights[access_type]: |
352 check(request) |
364 check(request) |
353 |
365 |
354 # All checks were successfull |
|
355 return |
|
356 |
|
357 def collectCleanedFields(self, form): |
366 def collectCleanedFields(self, form): |
358 """Collects all cleaned fields from form and returns them |
367 """Collects all cleaned fields from form and returns them |
359 |
368 |
360 Args: |
369 Args: |
361 form: The form from which the cleaned fields should be collected |
370 form: The form from which the cleaned fields should be collected |