app/django/views/generic/create_update.py
changeset 54 03e267d67478
child 323 ff1a9aa48cfd
equal deleted inserted replaced
53:57b4279d8c4e 54:03e267d67478
       
     1 from django.core.xheaders import populate_xheaders
       
     2 from django.template import loader
       
     3 from django import oldforms
       
     4 from django.db.models import FileField
       
     5 from django.contrib.auth.views import redirect_to_login
       
     6 from django.template import RequestContext
       
     7 from django.http import Http404, HttpResponse, HttpResponseRedirect
       
     8 from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured
       
     9 from django.utils.translation import ugettext
       
    10 
       
    11 def create_object(request, model, template_name=None,
       
    12         template_loader=loader, extra_context=None, post_save_redirect=None,
       
    13         login_required=False, follow=None, context_processors=None):
       
    14     """
       
    15     Generic object-creation function.
       
    16 
       
    17     Templates: ``<app_label>/<model_name>_form.html``
       
    18     Context:
       
    19         form
       
    20             the form wrapper for the object
       
    21     """
       
    22     if extra_context is None: extra_context = {}
       
    23     if login_required and not request.user.is_authenticated():
       
    24         return redirect_to_login(request.path)
       
    25 
       
    26     manipulator = model.AddManipulator(follow=follow)
       
    27     if request.POST:
       
    28         # If data was POSTed, we're trying to create a new object
       
    29         new_data = request.POST.copy()
       
    30 
       
    31         if model._meta.has_field_type(FileField):
       
    32             new_data.update(request.FILES)
       
    33 
       
    34         # Check for errors
       
    35         errors = manipulator.get_validation_errors(new_data)
       
    36         manipulator.do_html2python(new_data)
       
    37 
       
    38         if not errors:
       
    39             # No errors -- this means we can save the data!
       
    40             new_object = manipulator.save(new_data)
       
    41 
       
    42             if request.user.is_authenticated():
       
    43                 request.user.message_set.create(message=ugettext("The %(verbose_name)s was created successfully.") % {"verbose_name": model._meta.verbose_name})
       
    44 
       
    45             # Redirect to the new object: first by trying post_save_redirect,
       
    46             # then by obj.get_absolute_url; fail if neither works.
       
    47             if post_save_redirect:
       
    48                 return HttpResponseRedirect(post_save_redirect % new_object.__dict__)
       
    49             elif hasattr(new_object, 'get_absolute_url'):
       
    50                 return HttpResponseRedirect(new_object.get_absolute_url())
       
    51             else:
       
    52                 raise ImproperlyConfigured("No URL to redirect to from generic create view.")
       
    53     else:
       
    54         # No POST, so we want a brand new form without any data or errors
       
    55         errors = {}
       
    56         new_data = manipulator.flatten_data()
       
    57 
       
    58     # Create the FormWrapper, template, context, response
       
    59     form = oldforms.FormWrapper(manipulator, new_data, errors)
       
    60     if not template_name:
       
    61         template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower())
       
    62     t = template_loader.get_template(template_name)
       
    63     c = RequestContext(request, {
       
    64         'form': form,
       
    65     }, context_processors)
       
    66     for key, value in extra_context.items():
       
    67         if callable(value):
       
    68             c[key] = value()
       
    69         else:
       
    70             c[key] = value
       
    71     return HttpResponse(t.render(c))
       
    72 
       
    73 def update_object(request, model, object_id=None, slug=None,
       
    74         slug_field='slug', template_name=None, template_loader=loader,
       
    75         extra_context=None, post_save_redirect=None,
       
    76         login_required=False, follow=None, context_processors=None,
       
    77         template_object_name='object'):
       
    78     """
       
    79     Generic object-update function.
       
    80 
       
    81     Templates: ``<app_label>/<model_name>_form.html``
       
    82     Context:
       
    83         form
       
    84             the form wrapper for the object
       
    85         object
       
    86             the original object being edited
       
    87     """
       
    88     if extra_context is None: extra_context = {}
       
    89     if login_required and not request.user.is_authenticated():
       
    90         return redirect_to_login(request.path)
       
    91 
       
    92     # Look up the object to be edited
       
    93     lookup_kwargs = {}
       
    94     if object_id:
       
    95         lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id
       
    96     elif slug and slug_field:
       
    97         lookup_kwargs['%s__exact' % slug_field] = slug
       
    98     else:
       
    99         raise AttributeError("Generic edit view must be called with either an object_id or a slug/slug_field")
       
   100     try:
       
   101         object = model.objects.get(**lookup_kwargs)
       
   102     except ObjectDoesNotExist:
       
   103         raise Http404, "No %s found for %s" % (model._meta.verbose_name, lookup_kwargs)
       
   104 
       
   105     manipulator = model.ChangeManipulator(getattr(object, object._meta.pk.attname), follow=follow)
       
   106 
       
   107     if request.POST:
       
   108         new_data = request.POST.copy()
       
   109         if model._meta.has_field_type(FileField):
       
   110             new_data.update(request.FILES)
       
   111         errors = manipulator.get_validation_errors(new_data)
       
   112         manipulator.do_html2python(new_data)
       
   113         if not errors:
       
   114             object = manipulator.save(new_data)
       
   115 
       
   116             if request.user.is_authenticated():
       
   117                 request.user.message_set.create(message=ugettext("The %(verbose_name)s was updated successfully.") % {"verbose_name": model._meta.verbose_name})
       
   118 
       
   119             # Do a post-after-redirect so that reload works, etc.
       
   120             if post_save_redirect:
       
   121                 return HttpResponseRedirect(post_save_redirect % object.__dict__)
       
   122             elif hasattr(object, 'get_absolute_url'):
       
   123                 return HttpResponseRedirect(object.get_absolute_url())
       
   124             else:
       
   125                 raise ImproperlyConfigured("No URL to redirect to from generic create view.")
       
   126     else:
       
   127         errors = {}
       
   128         # This makes sure the form acurate represents the fields of the place.
       
   129         new_data = manipulator.flatten_data()
       
   130 
       
   131     form = oldforms.FormWrapper(manipulator, new_data, errors)
       
   132     if not template_name:
       
   133         template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower())
       
   134     t = template_loader.get_template(template_name)
       
   135     c = RequestContext(request, {
       
   136         'form': form,
       
   137         template_object_name: object,
       
   138     }, context_processors)
       
   139     for key, value in extra_context.items():
       
   140         if callable(value):
       
   141             c[key] = value()
       
   142         else:
       
   143             c[key] = value
       
   144     response = HttpResponse(t.render(c))
       
   145     populate_xheaders(request, response, model, getattr(object, object._meta.pk.attname))
       
   146     return response
       
   147 
       
   148 def delete_object(request, model, post_delete_redirect,
       
   149         object_id=None, slug=None, slug_field='slug', template_name=None,
       
   150         template_loader=loader, extra_context=None,
       
   151         login_required=False, context_processors=None, template_object_name='object'):
       
   152     """
       
   153     Generic object-delete function.
       
   154 
       
   155     The given template will be used to confirm deletetion if this view is
       
   156     fetched using GET; for safty, deletion will only be performed if this
       
   157     view is POSTed.
       
   158 
       
   159     Templates: ``<app_label>/<model_name>_confirm_delete.html``
       
   160     Context:
       
   161         object
       
   162             the original object being deleted
       
   163     """
       
   164     if extra_context is None: extra_context = {}
       
   165     if login_required and not request.user.is_authenticated():
       
   166         return redirect_to_login(request.path)
       
   167 
       
   168     # Look up the object to be edited
       
   169     lookup_kwargs = {}
       
   170     if object_id:
       
   171         lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id
       
   172     elif slug and slug_field:
       
   173         lookup_kwargs['%s__exact' % slug_field] = slug
       
   174     else:
       
   175         raise AttributeError("Generic delete view must be called with either an object_id or a slug/slug_field")
       
   176     try:
       
   177         object = model._default_manager.get(**lookup_kwargs)
       
   178     except ObjectDoesNotExist:
       
   179         raise Http404, "No %s found for %s" % (model._meta.app_label, lookup_kwargs)
       
   180 
       
   181     if request.method == 'POST':
       
   182         object.delete()
       
   183         if request.user.is_authenticated():
       
   184             request.user.message_set.create(message=ugettext("The %(verbose_name)s was deleted.") % {"verbose_name": model._meta.verbose_name})
       
   185         return HttpResponseRedirect(post_delete_redirect)
       
   186     else:
       
   187         if not template_name:
       
   188             template_name = "%s/%s_confirm_delete.html" % (model._meta.app_label, model._meta.object_name.lower())
       
   189         t = template_loader.get_template(template_name)
       
   190         c = RequestContext(request, {
       
   191             template_object_name: object,
       
   192         }, context_processors)
       
   193         for key, value in extra_context.items():
       
   194             if callable(value):
       
   195                 c[key] = value()
       
   196             else:
       
   197                 c[key] = value
       
   198         response = HttpResponse(t.render(c))
       
   199         populate_xheaders(request, response, model, getattr(object, object._meta.pk.attname))
       
   200         return response