app/soc/views/models/base.py
changeset 399 b82852e6963e
parent 389 9b873166d7d5
child 402 021e86368600
equal deleted inserted replaced
398:aa1e786a0b1d 399:b82852e6963e
    46 
    46 
    47   self._logic: the logic singleton for this entity
    47   self._logic: the logic singleton for this entity
    48   """
    48   """
    49 
    49 
    50   DEF_SUBMIT_MSG_PARAM_NAME = 's'
    50   DEF_SUBMIT_MSG_PARAM_NAME = 's'
       
    51   DEF_SUBMIT_MSG_PROFILE_SAVED = 0
    51 
    52 
    52   DEF_CREATE_NEW_ENTITY_MSG = ugettext_lazy(
    53   DEF_CREATE_NEW_ENTITY_MSG = ugettext_lazy(
    53       ' You can create a new %(model_type)s by visiting'
    54       ' You can create a new %(entity_type_lower)s by visiting'
    54       ' <a href="%(create)s">Create '
    55       ' <a href="%(create)s">Create '
    55       'a New %(Type)s</a> page.')
    56       'a New %(entity_type)s</a> page.')
    56 
    57 
    57   def __init__(self, params=None, rights=None):
    58   def __init__(self, params=None, rights=None):
    58     """
    59     """
    59 
    60 
    60     Args:
    61     Args:
   104     entity = None
   105     entity = None
   105 
   106 
   106     try:
   107     try:
   107       entity = self._logic.getIfFields(**kwargs)
   108       entity = self._logic.getIfFields(**kwargs)
   108     except soc.logic.out_of_band.ErrorResponse, error:
   109     except soc.logic.out_of_band.ErrorResponse, error:
   109       template = _params['public_template']
   110       template = self._params['public_template']
   110       return simple.errorResponse(request, error, template, context)
   111       return simple.errorResponse(request, page, error, template, context)
   111 
   112 
   112     if not entity:
   113     if not entity:
   113       #TODO: Change this into a proper redirect
   114       #TODO: Change this into a proper redirect
   114       return http.HttpResponseRedirect('/')
   115       return http.HttpResponseRedirect('/')
   115 
       
   116     self._makePublic(entity)
       
   117 
   116 
   118     context['entity'] = entity
   117     context['entity'] = entity
   119     context['entity_type'] = self._params['name']
   118     context['entity_type'] = self._params['name']
   120 
   119 
   121     template = self._params['public_template']
   120     template = self._params['public_template']
   131         that combines a Django view with sidebar menu info
   130         that combines a Django view with sidebar menu info
   132       kwargs: not used for create()
   131       kwargs: not used for create()
   133     """
   132     """
   134 
   133 
   135     # Create page is an edit page with no key fields
   134     # Create page is an edit page with no key fields
   136     kwargs = {}
   135     kwargs = self._logic.getEmptyKeyFields()
   137     return self.edit(request, page=page, **kwargs)
   136     return self.edit(request, page=page, **kwargs)
   138 
   137 
   139   def edit(self, request, page=None, **kwargs):
   138   def edit(self, request, page=None, **kwargs):
   140     """Displays the public page for the entity specified by **kwargs
   139     """Displays the public page for the entity specified by **kwargs
   141 
   140 
   156     entity = None
   155     entity = None
   157 
   156 
   158     try:
   157     try:
   159       entity = self._logic.getIfFields(**kwargs)
   158       entity = self._logic.getIfFields(**kwargs)
   160     except soc.logic.out_of_band.ErrorResponse, error:
   159     except soc.logic.out_of_band.ErrorResponse, error:
   161       template = soc._params['public_template']
   160       template = self._params['public_template']
   162       error.message = error.message + self.DEF_CREATE_NEW_ENTITY_MSG % {
   161       error.message = error.message + View.DEF_CREATE_NEW_ENTITY_MSG % {
   163           'entity_type_lower' : self._params['name_lower'],
   162           'entity_type_lower' : self._params['name'].lower(),
   164           'entity_type_upper' : self._parmas['name_upper'],
   163           'entity_type' : self._params['name'],
   165           'create' : self._redirects['create']
   164           'create' : self._params['create_redirect']
   166           }
   165           }
   167       return simple.errorResponse(request, error, template, context)
   166       return simple.errorResponse(request, page, error, template, context)
   168 
   167 
   169     if request.method == 'POST':
   168     if request.method == 'POST':
   170       return self.editPost(request, entity, context)
   169       return self.editPost(request, entity, context)
   171     else:
   170     else:
   172       return self.editGet(request, entity, context)
   171       return self.editGet(request, entity, context)
   173 
   172 
   174   def editPost(self, request, entity, context):
   173   def editPost(self, request, entity, context):
   175     """Same as edit, but on POST
   174     """Same as edit, but on POST
   176     """
   175     """
       
   176 
   177     if entity:
   177     if entity:
   178       form = self._params['edit_form'](request.POST)
   178       form = self._params['edit_form'](request.POST)
   179     else:
   179     else:
   180       form = self._params['create_form'](request.POST)
   180       form = self._params['create_form'](request.POST)
   181 
   181 
   182     if not form.is_valid():
   182     if not form.is_valid():
   183       return
   183       return self._constructResponse(request, entity, context, form)
   184 
   184 
   185     fields = self.collectCleanedFields(form)
   185     fields = self.collectCleanedFields(form)
   186 
   186 
   187     self._editPost(request, entity, fields)
   187     self._editPost(request, entity, fields)
   188 
   188 
   191 
   191 
   192     if not entity:
   192     if not entity:
   193       return http.HttpResponseRedirect('/')
   193       return http.HttpResponseRedirect('/')
   194 
   194 
   195     params = self._params['edit_params']
   195     params = self._params['edit_params']
   196     # TODO(SRabbelier): Construct a suffix
   196     suffix = self._logic.constructKeyNameSuffix(fields)
   197     suffix = None
       
   198 
   197 
   199     # redirect to (possibly new) location of the entity
   198     # redirect to (possibly new) location of the entity
   200     # (causes 'Profile saved' message to be displayed)
   199     # (causes 'Profile saved' message to be displayed)
   201     return helper.responses.redirectToChangedSuffix(
   200     return helper.responses.redirectToChangedSuffix(
   202         request, None, suffix,
   201         request, suffix, suffix,
   203         params=params)
   202         params=params)
   204 
   203 
   205   def editGet(self, request, entity, context):
   204   def editGet(self, request, entity, context):
   206     """Same as edit, but on GET
   205     """Same as edit, but on GET
   207     """
   206     """
   209     suffix = None    
   208     suffix = None    
   210 
   209 
   211     # Remove the params from the request, this is relevant only if
   210     # Remove the params from the request, this is relevant only if
   212     # someone bookmarked a POST page.
   211     # someone bookmarked a POST page.
   213     is_self_referrer = helper.requests.isReferrerSelf(request, suffix=suffix)
   212     is_self_referrer = helper.requests.isReferrerSelf(request, suffix=suffix)
   214     if request.GET.get(self.DEF_SUBMIT_MSG_PARAM_NAME):
   213     if request.GET.get(View.DEF_SUBMIT_MSG_PARAM_NAME):
   215       if (not entity) or (not is_self_referrer):
   214       if (not entity) or (not is_self_referrer):
   216         return http.HttpResponseRedirect(request.path)
   215         return http.HttpResponseRedirect(request.path)
   217 
   216 
   218     if entity:
   217     if entity:
   219       # Note: no message will be displayed if parameter is not present
   218       # Note: no message will be displayed if parameter is not present
   220       context['notice'] = helper.requests.getSingleIndexedParamValue(
   219       context['notice'] = helper.requests.getSingleIndexedParamValue(
   221           request, self.DEF_SUBMIT_MSG_PARAM_NAME,
   220           request, View.DEF_SUBMIT_MSG_PARAM_NAME,
   222           values=self._params['save_message'])
   221           values=self._params['save_message'])
   223 
   222 
   224       # populate form with the existing entity
   223       # populate form with the existing entity
   225       form = self._params['edit_form'](instance=entity)
   224       form = self._params['edit_form'](instance=entity)
       
   225       self._editGet(request, entity, form)
   226     else:
   226     else:
   227       form = self._params['create_form']()
   227       form = self._params['create_form']()
       
   228 
       
   229     return self._constructResponse(request, entity, context, form)
       
   230 
       
   231   def list(self, request, page=None):
       
   232     """Displays the list page for the entity type
       
   233     
       
   234     Args:
       
   235       request: the standard Django HTTP request object
       
   236       page: a soc.logic.site.page.Page object which is abstraction
       
   237         that combines a Django view with sidebar menu info
       
   238     """
       
   239 
       
   240     try:
       
   241       self.checkAccess('list', request)
       
   242     except soc.views.out_of_band.AccessViolationResponse, alt_response:
       
   243       return alt_response.response()
       
   244 
       
   245     context = helper.responses.getUniversalContext(request)
       
   246     context['page'] = page
       
   247 
       
   248     offset, limit = helper.lists.cleanListParameters(
       
   249       offset=request.GET.get('offset'), limit=request.GET.get('limit'))
       
   250 
       
   251     # Fetch one more to see if there should be a 'next' link
       
   252     entities = self._logic.getForLimitAndOffset(limit + 1, offset=offset)
       
   253 
       
   254     context['pagination_form'] = helper.lists.makePaginationForm(request, limit)
       
   255 
       
   256     templates = self._params['lists_template']
       
   257 
       
   258     context = helper.lists.setList(request, context, entities, 
       
   259                                  offset, limit, templates)
       
   260 
       
   261     context['entity_type'] = self._params['name']
       
   262     context['entity_type_plural'] = self._params['name_plural']
       
   263 
       
   264     template = self._params['list_template']
       
   265 
       
   266     return helper.responses.respond(request, template, context)
       
   267 
       
   268   def delete(self, request, page=None, **kwargs):
       
   269     """Shows the delete page for the entity specified by kwargs
       
   270 
       
   271     Args:
       
   272       request: the standard Django HTTP request object
       
   273       page: a soc.logic.site.page.Page object which is abstraction
       
   274         that combines a Django view with sidebar menu info
       
   275       kwargs: The Key Fields for the specified entity
       
   276     """
       
   277 
       
   278     try:
       
   279       self.checkAccess('delete', request)
       
   280     except soc.views.out_of_band.AccessViolationResponse, alt_response:
       
   281       return alt_response.response()
       
   282 
       
   283     # create default template context for use with any templates
       
   284     context = helper.responses.getUniversalContext(request)
       
   285     context['page'] = page
       
   286     entity = None
       
   287 
       
   288     try:
       
   289       entity = self._logic.getIfFields(**kwargs)
       
   290     except soc.logic.out_of_band.ErrorResponse, error:
       
   291       template = self._params['create_template']
       
   292       error.message = error.message + View.DEF_CREATE_NEW_ENTITY_MSG % {
       
   293           'entity_type_lower' : self._params['name'].lower(),
       
   294           'entity_type' : self._params['name'],
       
   295           'create' : self._params['create_redirect']
       
   296           }
       
   297       return simple.errorResponse(request, page, error, template, context)
       
   298 
       
   299     if not entity:
       
   300       #TODO: Create a proper error page for this
       
   301       return http.HttpResponseRedirect('/')
       
   302 
       
   303     if not self._logic.isDeletable(entity):
       
   304       # TODO: Update the notice area telling the user that they
       
   305       # can't delete the entity
       
   306       pass
       
   307 
       
   308     self._logic.delete(entity)
       
   309     redirect = self._params['delete_redirect']
       
   310 
       
   311     return http.HttpResponseRedirect(redirect)
       
   312 
       
   313   def _editPost(self, request, entity, fields):
       
   314     """Performs any required processing on the entity to post its edit page
       
   315 
       
   316     Args:
       
   317       request: the django request object
       
   318       entity: the entity to post
       
   319       fields: the new field values
       
   320     """
       
   321 
       
   322     raise NotImplementedError
       
   323 
       
   324   def _editGet(self, request, entity, form):
       
   325     """Performs any required processing on the form to get its edit page
       
   326 
       
   327     Args:
       
   328       request: the django request object
       
   329       entity: the entity to get
       
   330       form: the django form that will be used for the page
       
   331     """
       
   332 
       
   333     pass
       
   334 
       
   335   def checkUnspecified(self, access_type, request):
       
   336     """Checks whether an unspecified access_type should be allowed
       
   337 
       
   338     Args:
       
   339       access_type: the access type (such as 'list' or 'edit') that was
       
   340                    not present in the _rights dictionary when checking.
       
   341     """
       
   342 
       
   343     pass
       
   344 
       
   345   def _constructResponse(self, request, entity, context, form):
       
   346     """Updates the context and returns a response for the specified arguments
       
   347 
       
   348     Args:
       
   349       request: the django request object
       
   350       entity: the entity that is used
       
   351       context: the context to be used
       
   352       form: the form that will be used
       
   353     """
   228 
   354 
   229     context['form'] = form
   355     context['form'] = form
   230     context['entity'] = entity
   356     context['entity'] = entity
   231     context['entity_type'] = self._params['name']
   357     context['entity_type'] = self._params['name']
   232     context['entity_type_plural'] = self._params['name_plural']
   358     context['entity_type_plural'] = self._params['name_plural']
   233 
   359 
   234     template = self._params['edit_template']
   360     template = self._params['edit_template']
   235 
   361 
   236     return helper.responses.respond(request, template, context)
   362     return helper.responses.respond(request, template, context)
   237 
   363 
   238   def list(self, request, page=None):
       
   239     """Displays the list page for the entity type
       
   240     
       
   241     Args:
       
   242       request: the standard Django HTTP request object
       
   243       page: a soc.logic.site.page.Page object which is abstraction
       
   244         that combines a Django view with sidebar menu info
       
   245     """
       
   246 
       
   247     try:
       
   248       self.checkAccess('list', request)
       
   249     except soc.views.out_of_band.AccessViolationResponse, alt_response:
       
   250       return alt_response.response()
       
   251 
       
   252     context = helper.responses.getUniversalContext(request)
       
   253     context['page'] = page
       
   254 
       
   255     offset, limit = helper.lists.cleanListParameters(
       
   256       offset=request.GET.get('offset'), limit=request.GET.get('limit'))
       
   257 
       
   258     # Fetch one more to see if there should be a 'next' link
       
   259     entities = self._logic.getForLimitAndOffset(limit + 1, offset=offset)
       
   260 
       
   261     context['pagination_form'] = helper.lists.makePaginationForm(request, limit)
       
   262 
       
   263     templates = self._params['lists_template']
       
   264 
       
   265     context = helper.lists.setList(request, context, entities, 
       
   266                                  offset, limit, templates)
       
   267 
       
   268     context['entity_type'] = self._params['name']
       
   269     context['entity_type_plural'] = self._params['name_plural']
       
   270 
       
   271     template = self._params['list_template']
       
   272 
       
   273     return helper.responses.respond(request, template, context)
       
   274 
       
   275   def delete(self, request, page=None, **kwargs):
       
   276     """Shows the delete page for the entity specified by kwargs
       
   277 
       
   278     Args:
       
   279       request: the standard Django HTTP request object
       
   280       page: a soc.logic.site.page.Page object which is abstraction
       
   281         that combines a Django view with sidebar menu info
       
   282       kwargs: The Key Fields for the specified entity
       
   283     """
       
   284 
       
   285     try:
       
   286       self.checkAccess('delete', request)
       
   287     except soc.views.out_of_band.AccessViolationResponse, alt_response:
       
   288       return alt_response.response()
       
   289 
       
   290     # create default template context for use with any templates
       
   291     context = helper.responses.getUniversalContext(request)
       
   292     context['page'] = page
       
   293     entity = None
       
   294 
       
   295     try:
       
   296       entity = models.sponsor.logic.getIfFields(**kwargs)
       
   297     except soc.logic.out_of_band.ErrorResponse, error:
       
   298       template = self._templates['create']
       
   299       error.message = error.message + self.DEF_CREATE_NEW_ENTITY_MSG % {
       
   300           'entity_type_lower' : self._name,
       
   301           'entity_type_upper' : self._Name,
       
   302            'create' : self._redirects['create']
       
   303            }
       
   304       return simple.errorResponse(request, error, template, context)
       
   305 
       
   306     if not entity:
       
   307       #TODO: Create a proper error page for this
       
   308       return http.HttpResponseRedirect('/')
       
   309 
       
   310     if not self._logic.isDeletable(entity):
       
   311       # TODO: Update the notice area telling the user that they
       
   312       # can't delete the entity
       
   313       pass
       
   314 
       
   315     self._logic.delete(entity)
       
   316     redirect = self._params['delete_redirect']
       
   317 
       
   318     return http.HttpResponseRedirect(redirect)
       
   319 
       
   320   def _editPost(self, request, entity, fields):
       
   321     """Performs any required processing on the entity to post its edit page
       
   322 
       
   323     Args:
       
   324       request: The django request object
       
   325       entity: the entity to make public
       
   326       fields: The new field values
       
   327     """
       
   328 
       
   329     raise NotImplementedError
       
   330 
       
   331   def checkUnspecified(self, access_type, request):
       
   332     """Checks whether an unspecified access_type should be allowed
       
   333 
       
   334     Args:
       
   335       access_type: the access type (such as 'list' or 'edit') that was
       
   336                    not present in the _rights dictionary when checking.
       
   337     """
       
   338 
       
   339     pass
       
   340 
       
   341   def checkAccess(self, access_type, request):
   364   def checkAccess(self, access_type, request):
   342     """Runs all the defined checks for the specified type
   365     """Runs all the defined checks for the specified type
   343 
   366 
   344     Args:
   367     Args:
   345       access_type: the type of request (such as 'list' or 'edit')
   368       access_type: the type of request (such as 'list' or 'edit')