1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
from django.core.xheaders import populate_xheaders
from django.template import loader
from django import forms
from django.db.models import FileField
from django.contrib.auth.views import redirect_to_login
from django.template import RequestContext
from django.http import Http404, HttpResponse, HttpResponseRedirect
from django.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
|