[cig-commits] r6252 - in cs/pythia/trunk/opal: . controllers views views/generic

leif at geodynamics.org leif at geodynamics.org
Tue Mar 13 17:11:41 PDT 2007


Author: leif
Date: 2007-03-13 17:11:40 -0700 (Tue, 13 Mar 2007)
New Revision: 6252

Added:
   cs/pythia/trunk/opal/controllers/
   cs/pythia/trunk/opal/controllers/Controller.py
   cs/pythia/trunk/opal/controllers/CreationController.py
   cs/pythia/trunk/opal/controllers/DeletionController.py
   cs/pythia/trunk/opal/controllers/FormController.py
   cs/pythia/trunk/opal/controllers/NoController.py
   cs/pythia/trunk/opal/controllers/UpdateController.py
   cs/pythia/trunk/opal/controllers/__init__.py
Removed:
   cs/pythia/trunk/opal/views/generic/create_update.py
Modified:
   cs/pythia/trunk/opal/views/DetailView.py
   cs/pythia/trunk/opal/views/ListView.py
   cs/pythia/trunk/opal/views/PaginatedListView.py
   cs/pythia/trunk/opal/views/View.py
Log:
Sketched-out OOP-ized create_object, update_object, and delete_object:
the Controller hierarchy.


Added: cs/pythia/trunk/opal/controllers/Controller.py
===================================================================
--- cs/pythia/trunk/opal/controllers/Controller.py	2007-03-13 23:38:22 UTC (rev 6251)
+++ cs/pythia/trunk/opal/controllers/Controller.py	2007-03-14 00:11:40 UTC (rev 6252)
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2007  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+class Controller(object):
+
+
+    def __init__(self):
+        self._view = None
+        self.model = None
+
+
+    def _getView(self):
+        return self._view
+    def _setView(self, view):
+        import weakref
+        self._view = weakref.proxy(view)
+        self.model = view.model
+    view = property(_getView, _setView)
+
+
+    def _getTemplateNameTag(self):
+        return self.view.defaultTemplateNameTag
+    templateNameTag = property(_getTemplateNameTag)
+
+
+    def globalContext(self):
+        return dict()
+
+
+    def response(self, request):
+        __pychecker__ = 'unusednames=request'
+        raise NotImplementedError("class %r must override 'response'" % self.__class__.__name__)
+
+
+    def decorateResponse(self, response, request):
+        return
+
+
+# end of file

Added: cs/pythia/trunk/opal/controllers/CreationController.py
===================================================================
--- cs/pythia/trunk/opal/controllers/CreationController.py	2007-03-13 23:38:22 UTC (rev 6251)
+++ cs/pythia/trunk/opal/controllers/CreationController.py	2007-03-14 00:11:40 UTC (rev 6252)
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2007  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from FormController import FormController
+
+
+class CreationController(FormController):
+    """
+    Generic object-creation controller.
+
+    Templates: ``<app_label>/<model_name>_form.html``
+    Context:
+        form
+            the form wrapper for the object
+    """
+
+
+    def newManipulator(self):
+        return self.model.AddManipulator(follow=self.follow)
+
+
+    def successMessage(self):
+        return "The %s was created successfully." % self.model._meta.verbose_name
+
+
+# end of file

Added: cs/pythia/trunk/opal/controllers/DeletionController.py
===================================================================
--- cs/pythia/trunk/opal/controllers/DeletionController.py	2007-03-13 23:38:22 UTC (rev 6251)
+++ cs/pythia/trunk/opal/controllers/DeletionController.py	2007-03-14 00:11:40 UTC (rev 6252)
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2007  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from Controller import Controller
+from opal.http import HttpResponseRedirect
+
+
+class DeletionController(Controller):
+    """
+    Generic object-deletion controller.
+
+    The given template will be used to confirm deletetion if the view is
+    fetched using GET; for safty, deletion will only be performed if the
+    method is POST.
+
+    Templates: ``<app_label>/<model_name>_confirm_delete.html``
+    Context:
+        object
+            the original object being deleted
+    """
+
+
+    templateNameTag = "confirm_delete"
+
+
+    def __init__(self, post_redirect=None, **kwds):
+        Controller.__init__(self, **kwds)
+        self.post_redirect = post_redirect
+
+
+    def response(self, request):
+
+        if request.method == "POST":
+            self.view.obj.delete()
+            if request.user.is_authenticated():
+                request.user.message_set.create(message="The %s was deleted." % self.model._meta.verbose_name)
+            return HttpResponseRedirect(self.post_redirect)
+
+        return self.view.render(request)
+
+
+# end of file

Added: cs/pythia/trunk/opal/controllers/FormController.py
===================================================================
--- cs/pythia/trunk/opal/controllers/FormController.py	2007-03-13 23:38:22 UTC (rev 6251)
+++ cs/pythia/trunk/opal/controllers/FormController.py	2007-03-14 00:11:40 UTC (rev 6252)
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2007  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from Controller import Controller
+from opal import forms
+from opal.core.exceptions import ImproperlyConfigured
+from opal.http import HttpResponseRedirect
+
+
+class FormController(Controller):
+
+
+    templateNameTag = "form"
+
+
+    def __init__(self, post_redirect=None, follow=None, **kwds):
+        Controller.__init__(self, **kwds)
+        self.post_redirect = post_redirect
+        self.follow = follow
+        self.data = None
+        self.errors = {}
+
+
+    def createGlobalContext(self):
+        context = dict()
+        form = self.newFormWrapper()
+        context['form'] = form
+        return context
+
+
+    def newFormWrapper(self):
+        return forms.FormWrapper(self.manipulator, self.data, self.errors)
+
+
+    def getData(self, request):
+        method = request.method
+        if method == "POST":
+            # If data was POSTed, we're trying to create a new object
+            self.getPostedData(request)
+        elif method == "GET":
+            # No POST, so we want a brand new form without any data or errors
+            self.getBlankData(request)
+        else:
+            raise ValueError("unknown method: '%s'" % method)
+
+
+    def getPostedData(self, request):
+        from opal.db.models import FileField
+        data = request.POST.copy()
+        self.data = data
+        if self.model._meta.has_field_type(FileField):
+            data.update(request.FILES)
+        # Check for errors
+        self.errors = self.manipulator.get_validation_errors(data)
+        self.manipulator.do_html2python(data)
+
+
+    def getBlankData(self, request):
+        __pychecker__ = 'unusednames=request'
+        # This makes sure the form acurately represents the fields of the place.
+        self.data = self.manipulator.flatten_data()
+
+
+    def response(self, request):
+        self.manipulator = self.newManipulator()
+        self.getData(request)
+        
+        if request.method != "POST" or self.errors:
+            # Let the view respond to this request.
+            return self.view.render(request)
+
+        # POST with no errors -- this means we can save the data!
+        obj = self.manipulator.save(self.data)
+
+        if request.user.is_authenticated():
+            request.user.message_set.create(message=self.successMessage())
+
+        # Do a post-after-redirect so that reload works, etc.
+        # Redirect to the new object: first by trying post_redirect,
+        # then by obj.get_absolute_url; fail if neither works.
+        if self.post_redirect:
+            redirect_to = self.post_redirect % obj.__dict__
+        elif hasattr(obj, 'get_absolute_url'):
+            redirect_to = obj.get_absolute_url()
+        else:
+            raise ImproperlyConfigured("No URL to redirect to.")
+
+        return HttpResponseRedirect(redirect_to)
+
+
+    def newManipulator(self):
+        raise NotImplementedError()
+
+
+    def successMessage(self):
+        raise NotImplementedError()
+
+
+# end of file

Added: cs/pythia/trunk/opal/controllers/NoController.py
===================================================================
--- cs/pythia/trunk/opal/controllers/NoController.py	2007-03-13 23:38:22 UTC (rev 6251)
+++ cs/pythia/trunk/opal/controllers/NoController.py	2007-03-14 00:11:40 UTC (rev 6252)
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2007  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from Controller import Controller
+
+
+class NoController(Controller):
+
+
+    def response(self, request):
+        return self.view.render(request)
+
+
+# end of file

Added: cs/pythia/trunk/opal/controllers/UpdateController.py
===================================================================
--- cs/pythia/trunk/opal/controllers/UpdateController.py	2007-03-13 23:38:22 UTC (rev 6251)
+++ cs/pythia/trunk/opal/controllers/UpdateController.py	2007-03-14 00:11:40 UTC (rev 6252)
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2007  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from FormController import FormController
+from opal.core.xheaders import populate_xheaders
+
+
+class UpdateController(FormController):
+    """
+    Generic object-update controller.
+
+    Templates: ``<app_label>/<model_name>_form.html``
+    Context:
+        form
+            the form wrapper for the object
+        object
+            the original object being edited
+    """
+
+
+    templateNameTag = "form"
+
+    
+    def newManipulator(self):
+        obj = self.view.obj
+        return self.model.ChangeManipulator(getattr(obj, obj._meta.pk.name), follow=self.follow)
+
+
+    def successMessage(self):
+        return "The %s was updated successfully." % self.model._meta.verbose_name
+
+
+    def decorateResponse(self, response, request):
+        super(UpdateController, self).decorateResponse(response, request)
+        obj = self.view.obj
+        populate_xheaders(request, response, self.model, getattr(obj, obj._meta.pk.name))
+        return
+
+
+# end of file

Added: cs/pythia/trunk/opal/controllers/__init__.py
===================================================================
--- cs/pythia/trunk/opal/controllers/__init__.py	2007-03-13 23:38:22 UTC (rev 6251)
+++ cs/pythia/trunk/opal/controllers/__init__.py	2007-03-14 00:11:40 UTC (rev 6252)
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2007  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from Controller import Controller
+from NoController import NoController
+from FormController import FormController
+from CreationController import CreationController
+from UpdateController import UpdateController
+from DeletionController import DeletionController
+
+
+# end of file

Modified: cs/pythia/trunk/opal/views/DetailView.py
===================================================================
--- cs/pythia/trunk/opal/views/DetailView.py	2007-03-13 23:38:22 UTC (rev 6251)
+++ cs/pythia/trunk/opal/views/DetailView.py	2007-03-14 00:11:40 UTC (rev 6252)
@@ -12,9 +12,9 @@
 
 
 from View import View
+from opal.core.exceptions import ObjectDoesNotExist
+from opal.http import Http404, HttpResponse
 from opal.template import RequestContext
-from opal.http import Http404, HttpResponse
-from opal.core.xheaders import populate_xheaders
 
 
 class DetailView(View):
@@ -28,38 +28,58 @@
     """
 
 
-    templateNameTag = "detail"
+    defaultTemplateNameTag = "detail"
 
 
-    def __init__(self, queryset, query,
-                 template_name_field=None, **kwds):
-        View.__init__(self, queryset=queryset, **kwds)
+    def __init__(self, model, query, template_name_field=None, **kwds):
+        View.__init__(self, model, **kwds)
         self.query = query
+        self.obj = None
         self.template_name_field = template_name_field
         return
 
 
     def response(self, request):
-        model = self.queryset.model
-        try:
-            obj = self.query.get(self.queryset)
-        except ObjectDoesNotExist:
-            raise Http404, "No %s found matching the query '%s'" % (model._meta.verbose_name, query)
-        t = self.loadTemplate(obj)
-        c = RequestContext(request, {template_object_name: obj}, self.context_processors)
-        c = self.addExtraContext(c)
+        self.obj = self.getObject()
+        # Give the controller a chance to respond to this request.
+        return self.controller.response(request)
+
+
+    def render(self, request):
+        t = self.loadTemplate()
+        c = self.createContext(request)
         response = HttpResponse(t.render(c), mimetype=self.mimetype)
-        populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.name))
+        self.controller.decorateResponse(response, request)
         return response
 
 
-    def loadTemplate(self, obj):
+    def getObject(self):
+        try:
+            obj = self.query.get(self.model._default_manager.all())
+        except ObjectDoesNotExist:
+            raise Http404("No %s found matching the query '%s'" % (self.model._meta.verbose_name, self.query))
+        return obj
+
+
+    def loadTemplate(self):
         if self.template_name_field:
-            template_name_list = [getattr(obj, self.template_name_field), self.template_name]
+            template_name_list = [getattr(self.obj, self.template_name_field), self.template_name]
             t = self.template_loader.select_template(template_name_list)
         else:
             t = super(DetailView, self).loadTemplate()
         return t
 
 
+    def createContext(self, request):
+        c = RequestContext(request, self.globalContext(), self.context_processors)
+        c = self.addExtraContext(c)
+        return c
+
+
+    def globalContext(self):
+        context = super(DetailView, self).globalContext()
+        context[self.template_object_name] = self.obj
+        return context
+
+
 # end of file

Modified: cs/pythia/trunk/opal/views/ListView.py
===================================================================
--- cs/pythia/trunk/opal/views/ListView.py	2007-03-13 23:38:22 UTC (rev 6251)
+++ cs/pythia/trunk/opal/views/ListView.py	2007-03-14 00:11:40 UTC (rev 6252)
@@ -12,8 +12,8 @@
 
 
 from View import View
+from opal.http import Http404, HttpResponse
 from opal.template import RequestContext
-from opal.http import Http404, HttpResponse
 
 
 class ListView(View):
@@ -45,11 +45,12 @@
     """
 
 
-    templateNameTag = "list"
+    defaultTemplateNameTag = "list"
 
 
     def __init__(self, queryset, allow_empty=True, **kwds):
-        View.__init__(self, queryset=queryset, **kwds)
+        View.__init__(self, queryset.model, **kwds)
+        self.queryset = queryset
         self.allow_empty = allow_empty
         return
 
@@ -67,7 +68,7 @@
             'is_paginated': False
         }, self.context_processors)
         if not self.allow_empty and len(self.queryset) == 0:
-            raise Http404
+            raise Http404()
         return c
 
 

Modified: cs/pythia/trunk/opal/views/PaginatedListView.py
===================================================================
--- cs/pythia/trunk/opal/views/PaginatedListView.py	2007-03-13 23:38:22 UTC (rev 6251)
+++ cs/pythia/trunk/opal/views/PaginatedListView.py	2007-03-14 00:11:40 UTC (rev 6252)
@@ -13,6 +13,7 @@
 
 from ListView import ListView
 from opal.core.paginator import ObjectPaginator, InvalidPage
+from opal.http import Http404
 from opal.template import RequestContext
 
 
@@ -46,7 +47,7 @@
 
 
     def __init__(self, queryset, paginate_by, page=None, **kwds):
-        ListView.__init__(queryset=queryset, **kwds)
+        ListView.__init__(self, queryset, **kwds)
         self.paginate_by = paginate_by
         self.page = page
         return
@@ -65,7 +66,7 @@
             if page == 1 and self.allow_empty:
                 object_list = []
             else:
-                raise Http404
+                raise Http404()
         c = RequestContext(request, {
             '%s_list' % self.template_object_name: object_list,
             'is_paginated': paginator.pages > 1,

Modified: cs/pythia/trunk/opal/views/View.py
===================================================================
--- cs/pythia/trunk/opal/views/View.py	2007-03-13 23:38:22 UTC (rev 6251)
+++ cs/pythia/trunk/opal/views/View.py	2007-03-14 00:11:40 UTC (rev 6252)
@@ -14,18 +14,23 @@
 class View(object):
 
 
-    def __init__(self, queryset,
+    def __init__(self, model, controller=None,
                  template_name=None, template_loader=None,
                  extra_context=None, context_processors=None,
                  template_object_name='object',
                  mimetype=None):
-        self.queryset = queryset
+        self.model = model
+        if controller is None:
+            from opal.controllers import NoController
+            self.controller = NoController
+        else:
+            self.controller = controller
+        self.controller.view = self
         if template_name:
             self.template_name = template_name
         else:
-            model = queryset.model
-            template_name = "%s/%s_%s.html" % (model._meta.app_label,
-                                               model._meta.object_name.lower(),
+            template_name = "%s/%s_%s.html" % (self.model._meta.app_label,
+                                               self.model._meta.object_name.lower(),
                                                self.templateNameTag)
         if template_loader is None:
             from opal.template import loader
@@ -42,10 +47,16 @@
         return
 
 
-    def response(self):
+    def response(self, request):
+        __pychecker__ = 'unusednames=request'
         raise NotImplementedError("class %r must override 'response'" % self.__class__.__name__)
 
 
+    def _getTemplateNameTag(self):
+        return self.controller.templateNameTag
+    templateNameTag = property(_getTemplateNameTag)
+
+
     def loadTemplate(self):
         return self.template_loader.get_template(self.template_name)
 
@@ -59,4 +70,8 @@
         return c
 
 
+    def globalContext(self):
+        return self.controller.globalContext()
+
+
 # end of file

Deleted: cs/pythia/trunk/opal/views/generic/create_update.py
===================================================================
--- cs/pythia/trunk/opal/views/generic/create_update.py	2007-03-13 23:38:22 UTC (rev 6251)
+++ cs/pythia/trunk/opal/views/generic/create_update.py	2007-03-14 00:11:40 UTC (rev 6252)
@@ -1,199 +0,0 @@
-from opal.core.xheaders import populate_xheaders
-from opal.template import loader
-from opal import forms
-from opal.db.models import FileField
-from opal.contrib.auth.views import redirect_to_login
-from opal.template import RequestContext
-from opal.http import Http404, HttpResponse, HttpResponseRedirect
-from opal.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured
-
-def create_object(request, model, template_name=None,
-        template_loader=loader, extra_context=None, post_save_redirect=None,
-        login_required=False, follow=None, context_processors=None):
-    """
-    Generic object-creation function.
-
-    Templates: ``<app_label>/<model_name>_form.html``
-    Context:
-        form
-            the form wrapper for the object
-    """
-    if extra_context is None: extra_context = {}
-    if login_required and not request.user.is_authenticated():
-        return redirect_to_login(request.path)
-
-    manipulator = model.AddManipulator(follow=follow)
-    if request.POST:
-        # If data was POSTed, we're trying to create a new object
-        new_data = request.POST.copy()
-
-        if model._meta.has_field_type(FileField):
-            new_data.update(request.FILES)
-
-        # Check for errors
-        errors = manipulator.get_validation_errors(new_data)
-        manipulator.do_html2python(new_data)
-
-        if not errors:
-            # No errors -- this means we can save the data!
-            new_object = manipulator.save(new_data)
-
-            if request.user.is_authenticated():
-                request.user.message_set.create(message="The %s was created successfully." % model._meta.verbose_name)
-
-            # Redirect to the new object: first by trying post_save_redirect,
-            # then by obj.get_absolute_url; fail if neither works.
-            if post_save_redirect:
-                return HttpResponseRedirect(post_save_redirect % new_object.__dict__)
-            elif hasattr(new_object, 'get_absolute_url'):
-                return HttpResponseRedirect(new_object.get_absolute_url())
-            else:
-                raise ImproperlyConfigured("No URL to redirect to from generic create view.")
-    else:
-        # No POST, so we want a brand new form without any data or errors
-        errors = {}
-        new_data = manipulator.flatten_data()
-
-    # Create the FormWrapper, template, context, response
-    form = forms.FormWrapper(manipulator, new_data, errors)
-    if not template_name:
-        template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower())
-    t = template_loader.get_template(template_name)
-    c = RequestContext(request, {
-        'form': form,
-    }, context_processors)
-    for key, value in extra_context.items():
-        if callable(value):
-            c[key] = value()
-        else:
-            c[key] = value
-    return HttpResponse(t.render(c))
-
-def update_object(request, model, object_id=None, slug=None,
-        slug_field=None, template_name=None, template_loader=loader,
-        extra_context=None, post_save_redirect=None,
-        login_required=False, follow=None, context_processors=None,
-        template_object_name='object'):
-    """
-    Generic object-update function.
-
-    Templates: ``<app_label>/<model_name>_form.html``
-    Context:
-        form
-            the form wrapper for the object
-        object
-            the original object being edited
-    """
-    if extra_context is None: extra_context = {}
-    if login_required and not request.user.is_authenticated():
-        return redirect_to_login(request.path)
-
-    # Look up the object to be edited
-    lookup_kwargs = {}
-    if object_id:
-        lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id
-    elif slug and slug_field:
-        lookup_kwargs['%s__exact' % slug_field] = slug
-    else:
-        raise AttributeError("Generic edit view must be called with either an object_id or a slug/slug_field")
-    try:
-        object = model.objects.get(**lookup_kwargs)
-    except ObjectDoesNotExist:
-        raise Http404, "No %s found for %s" % (model._meta.verbose_name, lookup_kwargs)
-
-    manipulator = model.ChangeManipulator(getattr(object, object._meta.pk.name), follow=follow)
-
-    if request.POST:
-        new_data = request.POST.copy()
-        if model._meta.has_field_type(FileField):
-            new_data.update(request.FILES)
-        errors = manipulator.get_validation_errors(new_data)
-        manipulator.do_html2python(new_data)
-        if not errors:
-            object = manipulator.save(new_data)
-
-            if request.user.is_authenticated():
-                request.user.message_set.create(message="The %s was updated successfully." % model._meta.verbose_name)
-
-            # Do a post-after-redirect so that reload works, etc.
-            if post_save_redirect:
-                return HttpResponseRedirect(post_save_redirect % object.__dict__)
-            elif hasattr(object, 'get_absolute_url'):
-                return HttpResponseRedirect(object.get_absolute_url())
-            else:
-                raise ImproperlyConfigured("No URL to redirect to from generic create view.")
-    else:
-        errors = {}
-        # This makes sure the form acurate represents the fields of the place.
-        new_data = manipulator.flatten_data()
-
-    form = forms.FormWrapper(manipulator, new_data, errors)
-    if not template_name:
-        template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower())
-    t = template_loader.get_template(template_name)
-    c = RequestContext(request, {
-        'form': form,
-        template_object_name: object,
-    }, context_processors)
-    for key, value in extra_context.items():
-        if callable(value):
-            c[key] = value()
-        else:
-            c[key] = value
-    response = HttpResponse(t.render(c))
-    populate_xheaders(request, response, model, getattr(object, object._meta.pk.name))
-    return response
-
-def delete_object(request, model, post_delete_redirect,
-        object_id=None, slug=None, slug_field=None, template_name=None,
-        template_loader=loader, extra_context=None,
-        login_required=False, context_processors=None, template_object_name='object'):
-    """
-    Generic object-delete function.
-
-    The given template will be used to confirm deletetion if this view is
-    fetched using GET; for safty, deletion will only be performed if this
-    view is POSTed.
-
-    Templates: ``<app_label>/<model_name>_confirm_delete.html``
-    Context:
-        object
-            the original object being deleted
-    """
-    if extra_context is None: extra_context = {}
-    if login_required and not request.user.is_authenticated():
-        return redirect_to_login(request.path)
-
-    # Look up the object to be edited
-    lookup_kwargs = {}
-    if object_id:
-        lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id
-    elif slug and slug_field:
-        lookup_kwargs['%s__exact' % slug_field] = slug
-    else:
-        raise AttributeError("Generic delete view must be called with either an object_id or a slug/slug_field")
-    try:
-        object = model._default_manager.get(**lookup_kwargs)
-    except ObjectDoesNotExist:
-        raise Http404, "No %s found for %s" % (model._meta.app_label, lookup_kwargs)
-
-    if request.method == 'POST':
-        object.delete()
-        if request.user.is_authenticated():
-            request.user.message_set.create(message="The %s was deleted." % model._meta.verbose_name)
-        return HttpResponseRedirect(post_delete_redirect)
-    else:
-        if not template_name:
-            template_name = "%s/%s_confirm_delete.html" % (model._meta.app_label, model._meta.object_name.lower())
-        t = template_loader.get_template(template_name)
-        c = RequestContext(request, {
-            template_object_name: object,
-        }, context_processors)
-        for key, value in extra_context.items():
-            if callable(value):
-                c[key] = value()
-            else:
-                c[key] = value
-        response = HttpResponse(t.render(c))
-        populate_xheaders(request, response, model, getattr(object, object._meta.pk.name))
-        return response



More information about the cig-commits mailing list