Entry 781
form view factory
Submitted by st_sebastian
on May 16, 2008 at 12:26 p.m.
Language: Python. Code size: 4.8 KB.
def create_form_view (template_name, form_class, object_class = None, linked_class = None, allow_new = False ): """Create a view function as used in ``DynamicAuthedView`` It will render a ModelForm instantiated from *form_class* using the template defined by *template_name*, and an instance of *object_class* will underlie the form. If called with a POST request, it will save the form and redirect to the created objects (or the linked object; see below) page by calling get_absolute url. By setting allow_new to True, the view will be able to created new instances of *model_class*. By setting *linked_class*, any new instances will get this attribute set before instantiating the form, allowing ForeignKey Fields to be set in advanced (And preventing the user to screw up the integrity of the relations" """ obj_name = object_class and object_class.__name__.lower() or None linked_name = linked_class and linked_class.__name__.lower() or None def ret_view (request, **kwargs): """ This is where we build the view function. We know what keyword arguments it will get from the urlhandler based in the classes we got from create_from view: If allow_new was True, we can expect a boolean argumet 'is_new' to the view, defaulting to false. object_class results in an argument named as the lowercased classname, possibly None (meaning is_new is True and the form should create a new instance). if linked_class was defined, this will receive the object that was used to authenticate the request. """ if allow_new and kwargs.get('is_new', False): # Create a new instance of object_class here to assign to the form. obj = object_class() if linked_class is not None: # if we have a linked class, then obj_class is probably a join-table linked_obj = kwargs.get(linked_name, None) if linked_obj is not None: try: setattr(obj, linked_name , linked_obj) except: print "Failed to set %s attribute on %s instance" % (linked_name, object_class) # as we got None as object argument, replace it with the newly created instance kwargs[obj_name] = obj else: # We got one from the authenticator obj = kwargs.get(obj_name, None) form = None respond_options = { obj_name : obj } if allow_new: # Tell the template context this is a new instance respond_options['is_new'] = kwargs.get('is_new', False) if request.method == "GET": # First request (or after invalid data submitted) - simply render the form bound # to the instance form = form_class(instance = obj) respond_options['form'] = form return respond(request, template_name, **respond_options) elif request.method == "POST": # Reached after the form was submitted form = form_class(instance = kwargs[obj_name], data = request.POST, files = request.FILES) if form.is_valid(): # All responsibility for handling relationships or files # is given to the form, as we have little knowledge about the model here. form.save() # Check where to go from here. The form class may define this by a special # method ``get_redirect_url`` if hasattr(form, "get_redirect_url"): # Redirecting prevents a double-submit by the user hitting # the "back" button. return HttpResponseRedirect(form.get_redirect_url()) if linked_class is not None: # object_class is probably an extended join-table, so there is # little use in pointing there. Instead, use the related object. return HttpResponseRedirect(getattr(obj, linked_name).get_absolute_url()) else: # show the objects detail_page as a fallback return HttpResponseRedirect(obj.get_absolute_url()) else: # If the form was not complete (or invalid), simply render it again. respond_options['form'] = form return respond(request, template_name, **respond_options) else: return HttpResponseNotAllowed(['GET', 'POST']) return ret_view
This snippet took 0.01 seconds to highlight.
Back to the Entry List or Home.