From 28990ef07b3f67fc8db18ba345e2d47a80d74475 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Mon, 15 Jan 2007 01:53:11 +0000 Subject: [PATCH] newforms-admin: Renamed ModelAdminView to ModelAdmin, moved it into django.contrib.admin.options and put model imports within methods to avoid import-order problems git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@4326 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/admin/options.py | 346 +++++++++++++++++++++++++++++ django/contrib/admin/views/main.py | 334 +--------------------------- 2 files changed, 352 insertions(+), 328 deletions(-) create mode 100644 django/contrib/admin/options.py diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py new file mode 100644 index 0000000000..6c7ffd237d --- /dev/null +++ b/django/contrib/admin/options.py @@ -0,0 +1,346 @@ +from django import oldforms, template +from django.core.exceptions import ImproperlyConfigured, PermissionDenied +from django.db import models +from django.http import Http404, HttpResponse, HttpResponseRedirect +from django.shortcuts import get_object_or_404, render_to_response +from django.utils.html import escape +from django.utils.text import capfirst, get_text_list +import sets + +class IncorrectLookupParameters(Exception): + pass + +def unquote(s): + """ + Undo the effects of quote(). Based heavily on urllib.unquote(). + """ + mychr = chr + myatoi = int + list = s.split('_') + res = [list[0]] + myappend = res.append + del list[0] + for item in list: + if item[1:2]: + try: + myappend(mychr(myatoi(item[:2], 16)) + item[2:]) + except ValueError: + myappend('_' + item) + else: + myappend('_' + item) + return "".join(res) + +class ModelAdmin(object): + "Encapsulates all admin options and functionality for a given model." + def __init__(self, model): + self.model = model + self.opts = model._meta + + def __call__(self, request, url): + # Check that LogEntry, ContentType and the auth context processor are installed. + from django.conf import settings + if settings.DEBUG: + from django.contrib.contenttypes.models import ContentType + from django.contrib.admin.models import LogEntry + if not LogEntry._meta.installed: + raise ImproperlyConfigured("Put 'django.contrib.admin' in your INSTALLED_APPS setting in order to use the admin application.") + if not ContentType._meta.installed: + raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in your INSTALLED_APPS setting in order to use the admin application.") + if 'django.core.context_processors.auth' not in settings.TEMPLATE_CONTEXT_PROCESSORS: + raise ImproperlyConfigured("Put 'django.core.context_processors.auth' in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.") + + # Delegate to the appropriate method, based on the URL. + if url is None: + return self.change_list_view(request) + elif url.endswith('add'): + return self.add_view(request) + elif url.endswith('history'): + return self.history_view(request, unquote(url[:-8])) + elif url.endswith('delete'): + return self.delete_view(request, unquote(url[:-7])) + else: + return self.change_view(request, unquote(url)) + + def has_add_permission(self, request): + "Returns True if the given request has permission to add an object." + opts = self.opts + return request.user.has_perm(opts.app_label + '.' + opts.get_add_permission()) + + def has_change_permission(self, request, object_id): + """ + Returns True if the given request has permission to change the object + with the given object_id. + """ + opts = self.opts + return request.user.has_perm(opts.app_label + '.' + opts.get_change_permission()) + + def has_delete_permission(self, request, object_id): + """ + Returns True if the given request has permission to change the object + with the given object_id. + """ + opts = self.opts + return request.user.has_perm(opts.app_label + '.' + opts.get_delete_permission()) + + def add_view(self, request, show_delete=False, form_url='', post_url=None, post_url_continue='../%s/', object_id_override=None): + "The 'add' admin view for this model." + from django.contrib.admin.views.main import render_change_form + from django.contrib.contenttypes.models import ContentType + from django.contrib.admin.models import LogEntry, ADDITION + model = self.model + opts = model._meta + app_label = opts.app_label + + if not self.has_add_permission(request): + raise PermissionDenied + + if post_url is None: + if self.has_change_permission(request, None): + # redirect to list view + post_url = '../' + else: + # Object list will give 'Permission Denied', so go back to admin home + post_url = '../../../' + + manipulator = model.AddManipulator() + if request.POST: + new_data = request.POST.copy() + + if opts.has_field_type(models.FileField): + new_data.update(request.FILES) + + errors = manipulator.get_validation_errors(new_data) + manipulator.do_html2python(new_data) + + if not errors: + new_object = manipulator.save(new_data) + pk_value = new_object._get_pk_val() + LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, str(new_object), ADDITION) + msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_object} + # Here, we distinguish between different save types by checking for + # the presence of keys in request.POST. + if request.POST.has_key("_continue"): + request.user.message_set.create(message=msg + ' ' + _("You may edit it again below.")) + if request.POST.has_key("_popup"): + post_url_continue += "?_popup=1" + return HttpResponseRedirect(post_url_continue % pk_value) + if request.POST.has_key("_popup"): + if type(pk_value) is str: # Quote if string, so JavaScript doesn't think it's a variable. + pk_value = '"%s"' % pk_value.replace('"', '\\"') + return HttpResponse('' % \ + (pk_value, str(new_object).replace('"', '\\"'))) + elif request.POST.has_key("_addanother"): + request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name)) + return HttpResponseRedirect(request.path) + else: + request.user.message_set.create(message=msg) + return HttpResponseRedirect(post_url) + else: + # Add default data. + new_data = manipulator.flatten_data() + + # Override the defaults with GET params, if they exist. + new_data.update(dict(request.GET.items())) + + errors = {} + + # Populate the FormWrapper. + form = oldforms.FormWrapper(manipulator, new_data, errors) + + c = template.RequestContext(request, { + 'title': _('Add %s') % opts.verbose_name, + 'form': form, + 'is_popup': request.REQUEST.has_key('_popup'), + 'show_delete': show_delete, + }) + + if object_id_override is not None: + c['object_id'] = object_id_override + + return render_change_form(model, manipulator, c, add=True) + + def change_view(self, request, object_id): + "The 'change' admin view for this model." + from django.contrib.admin.views.main import render_change_form + from django.contrib.contenttypes.models import ContentType + from django.contrib.admin.models import LogEntry, CHANGE + model = self.model + opts = model._meta + app_label = opts.app_label + + if not self.has_change_permission(request, object_id): + raise PermissionDenied + + if request.POST and request.POST.has_key("_saveasnew"): + return self.add_view(request, form_url='../../add/') + + try: + manipulator = model.ChangeManipulator(object_id) + except model.DoesNotExist: + raise Http404('%s object with primary key %r does not exist' % (model_name, escape(object_id))) + + if request.POST: + new_data = request.POST.copy() + + if opts.has_field_type(models.FileField): + new_data.update(request.FILES) + + errors = manipulator.get_validation_errors(new_data) + manipulator.do_html2python(new_data) + + if not errors: + new_object = manipulator.save(new_data) + pk_value = new_object._get_pk_val() + + # Construct the change message. + change_message = [] + if manipulator.fields_added: + change_message.append(_('Added %s.') % get_text_list(manipulator.fields_added, _('and'))) + if manipulator.fields_changed: + change_message.append(_('Changed %s.') % get_text_list(manipulator.fields_changed, _('and'))) + if manipulator.fields_deleted: + change_message.append(_('Deleted %s.') % get_text_list(manipulator.fields_deleted, _('and'))) + change_message = ' '.join(change_message) + if not change_message: + change_message = _('No fields changed.') + LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, str(new_object), CHANGE, change_message) + + msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object} + if request.POST.has_key("_continue"): + request.user.message_set.create(message=msg + ' ' + _("You may edit it again below.")) + if request.REQUEST.has_key('_popup'): + return HttpResponseRedirect(request.path + "?_popup=1") + else: + return HttpResponseRedirect(request.path) + elif request.POST.has_key("_saveasnew"): + request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object}) + return HttpResponseRedirect("../%s/" % pk_value) + elif request.POST.has_key("_addanother"): + request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name)) + return HttpResponseRedirect("../add/") + else: + request.user.message_set.create(message=msg) + return HttpResponseRedirect("../") + else: + # Populate new_data with a "flattened" version of the current data. + new_data = manipulator.flatten_data() + + # TODO: do this in flatten_data... + # If the object has ordered objects on its admin page, get the existing + # order and flatten it into a comma-separated list of IDs. + id_order_list = [] + for rel_obj in opts.get_ordered_objects(): + id_order_list.extend(getattr(manipulator.original_object, 'get_%s_order' % rel_obj.object_name.lower())()) + if id_order_list: + new_data['order_'] = ','.join(map(str, id_order_list)) + errors = {} + + # Populate the FormWrapper. + form = oldforms.FormWrapper(manipulator, new_data, errors) + form.original = manipulator.original_object + form.order_objects = [] + + # TODO: Should be done in flatten_data / FormWrapper construction + for related in opts.get_followed_related_objects(): + wrt = related.opts.order_with_respect_to + if wrt and wrt.rel and wrt.rel.to == opts: + func = getattr(manipulator.original_object, 'get_%s_list' % + related.get_accessor_name()) + orig_list = func() + form.order_objects.extend(orig_list) + + c = template.RequestContext(request, { + 'title': _('Change %s') % opts.verbose_name, + 'form': form, + 'object_id': object_id, + 'original': manipulator.original_object, + 'is_popup': request.REQUEST.has_key('_popup'), + }) + return render_change_form(model, manipulator, c, change=True) + + def change_list_view(self, request): + "The 'change list' admin view for this model." + from django.contrib.admin.views.main import ChangeList, ERROR_FLAG + opts = self.model._meta + app_label = opts.app_label + if not self.has_change_permission(request, None): + raise PermissionDenied + try: + cl = ChangeList(request, self.model) + except IncorrectLookupParameters: + # Wacky lookup parameters were given, so redirect to the main + # changelist page, without parameters, and pass an 'invalid=1' + # parameter via the query string. If wacky parameters were given and + # the 'invalid=1' parameter was already in the query string, something + # is screwed up with the database, so display an error page. + if ERROR_FLAG in request.GET.keys(): + return render_to_response('admin/invalid_setup.html', {'title': _('Database error')}) + return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1') + c = template.RequestContext(request, { + 'title': cl.title, + 'is_popup': cl.is_popup, + 'cl': cl, + }) + c.update({'has_add_permission': c['perms'][app_label][opts.get_add_permission()]}), + return render_to_response(['admin/%s/%s/change_list.html' % (app_label, opts.object_name.lower()), + 'admin/%s/change_list.html' % app_label, + 'admin/change_list.html'], context_instance=c) + + def delete_view(self, request, object_id): + "The 'delete' admin view for this model." + from django.contrib.contenttypes.models import ContentType + from django.contrib.admin.models import LogEntry, DELETION + opts = self.model._meta + app_label = opts.app_label + if not self.has_delete_permission(request, object_id): + raise PermissionDenied + obj = get_object_or_404(self.model, pk=object_id) + + # Populate deleted_objects, a data structure of all related objects that + # will also be deleted. + deleted_objects = ['%s: %s' % (capfirst(opts.verbose_name), object_id, escape(str(obj))), []] + perms_needed = sets.Set() + _get_deleted_objects(deleted_objects, perms_needed, request.user, obj, opts, 1) + + if request.POST: # The user has already confirmed the deletion. + if perms_needed: + raise PermissionDenied + obj_display = str(obj) + obj.delete() + LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, object_id, obj_display, DELETION) + request.user.message_set.create(message=_('The %(name)s "%(obj)s" was deleted successfully.') % {'name': opts.verbose_name, 'obj': obj_display}) + return HttpResponseRedirect("../../") + extra_context = { + "title": _("Are you sure?"), + "object_name": opts.verbose_name, + "object": obj, + "deleted_objects": deleted_objects, + "perms_lacking": perms_needed, + "opts": opts, + } + return render_to_response(["admin/%s/%s/delete_confirmation.html" % (app_label, opts.object_name.lower() ), + "admin/%s/delete_confirmation.html" % app_label , + "admin/delete_confirmation.html"], extra_context, context_instance=template.RequestContext(request)) + + def history_view(self, request, object_id): + "The 'history' admin view for this model." + from django.contrib.contenttypes.models import ContentType + from django.contrib.admin.models import LogEntry + model = self.model + opts = model._meta + action_list = LogEntry.objects.filter(object_id=object_id, + content_type__id__exact=ContentType.objects.get_for_model(model).id).select_related().order_by('action_time') + # If no history was found, see whether this object even exists. + obj = get_object_or_404(model, pk=object_id) + extra_context = { + 'title': _('Change history: %s') % obj, + 'action_list': action_list, + 'module_name': capfirst(opts.verbose_name_plural), + 'object': obj, + } + template_list = [ + "admin/%s/%s/object_history.html" % (opts.app_label, opts.object_name.lower()), + "admin/%s/object_history.html" % opts.app_label, + "admin/object_history.html" + ] + return render_to_response(template_list, extra_context, context_instance=template.RequestContext(request)) diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 98acc63d8f..721f3453e5 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -1,26 +1,18 @@ -from django import oldforms, template -from django.conf import settings +from django import template from django.contrib.admin.filterspecs import FilterSpec +from django.contrib.admin.options import ModelAdmin, IncorrectLookupParameters from django.contrib.admin.views.decorators import staff_member_required from django.views.decorators.cache import never_cache from django.contrib.contenttypes.models import ContentType -from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist, PermissionDenied +from django.core.exceptions import ObjectDoesNotExist from django.core.paginator import ObjectPaginator, InvalidPage from django.shortcuts import get_object_or_404, render_to_response from django.db import models from django.db.models.query import handle_legacy_orderlist, QuerySet -from django.http import Http404, HttpResponse, HttpResponseRedirect +from django.http import Http404 from django.utils.html import escape -from django.utils.text import capfirst, get_text_list +from django.utils.text import capfirst import operator -import sets - -from django.contrib.admin.models import LogEntry, ADDITION, CHANGE, DELETION -if not LogEntry._meta.installed: - raise ImproperlyConfigured, "You'll need to put 'django.contrib.admin' in your INSTALLED_APPS setting before you can use the admin application." - -if 'django.core.context_processors.auth' not in settings.TEMPLATE_CONTEXT_PROCESSORS: - raise ImproperlyConfigured, "You'll need to put 'django.core.context_processors.auth' in your TEMPLATE_CONTEXT_PROCESSORS setting before you can use the admin application." # The system will display a "Show all" link on the change list only if the # total result count is less than or equal to this setting. @@ -40,9 +32,6 @@ EMPTY_CHANGELIST_VALUE = '(None)' use_raw_id_admin = lambda field: isinstance(field.rel, (models.ManyToOneRel, models.ManyToManyRel)) and field.rel.raw_id_admin -class IncorrectLookupParameters(Exception): - pass - def quote(s): """ Ensure that primary key values do not confuse the admin URLs by escaping @@ -59,26 +48,6 @@ def quote(s): res[i] = '_%02X' % ord(c) return ''.join(res) -def unquote(s): - """ - Undo the effects of quote(). Based heavily on urllib.unquote(). - """ - mychr = chr - myatoi = int - list = s.split('_') - res = [list[0]] - myappend = res.append - del list[0] - for item in list: - if item[1:2]: - try: - myappend(mychr(myatoi(item[:2], 16)) + item[2:]) - except ValueError: - myappend('_' + item) - else: - myappend('_' + item) - return "".join(res) - def get_javascript_imports(opts, auto_populated_fields, field_sets): # Put in any necessary JavaScript imports. js = ['js/core.js', 'js/admin/RelatedObjectLookups.js'] @@ -112,301 +81,10 @@ def model_admin_view(request, app_label, model_name, rest_of_url): raise Http404("App %r, model %r, not found" % (app_label, model_name)) if not model._meta.admin: raise Http404("This object has no admin interface.") - mav = ModelAdminView(model) + mav = ModelAdmin(model) return mav(request, rest_of_url) model_admin_view = staff_member_required(never_cache(model_admin_view)) -class ModelAdminView(object): - "Class that encapsulates all admin views for a given model." - def __init__(self, model): - self.model = model - self.opts = model._meta - - def __call__(self, request, url): - if url is None: - return self.change_list_view(request) - elif url.endswith('add'): - return self.add_view(request) - elif url.endswith('history'): - return self.history_view(request, unquote(url[:-8])) - elif url.endswith('delete'): - return self.delete_view(request, unquote(url[:-7])) - else: - return self.change_view(request, unquote(url)) - - def has_add_permission(self, request): - "Returns True if the given request has permission to add an object." - opts = self.opts - return request.user.has_perm(opts.app_label + '.' + opts.get_add_permission()) - - def has_change_permission(self, request, object_id): - """ - Returns True if the given request has permission to change the object - with the given object_id. - """ - opts = self.opts - return request.user.has_perm(opts.app_label + '.' + opts.get_change_permission()) - - def has_delete_permission(self, request, object_id): - """ - Returns True if the given request has permission to change the object - with the given object_id. - """ - opts = self.opts - return request.user.has_perm(opts.app_label + '.' + opts.get_delete_permission()) - - def add_view(self, request, show_delete=False, form_url='', post_url=None, post_url_continue='../%s/', object_id_override=None): - "The 'add' admin view for this model." - model = self.model - opts = model._meta - app_label = opts.app_label - - if not self.has_add_permission(request): - raise PermissionDenied - - if post_url is None: - if self.has_change_permission(request, None): - # redirect to list view - post_url = '../' - else: - # Object list will give 'Permission Denied', so go back to admin home - post_url = '../../../' - - manipulator = model.AddManipulator() - if request.POST: - new_data = request.POST.copy() - - if opts.has_field_type(models.FileField): - new_data.update(request.FILES) - - errors = manipulator.get_validation_errors(new_data) - manipulator.do_html2python(new_data) - - if not errors: - new_object = manipulator.save(new_data) - pk_value = new_object._get_pk_val() - LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, str(new_object), ADDITION) - msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_object} - # Here, we distinguish between different save types by checking for - # the presence of keys in request.POST. - if request.POST.has_key("_continue"): - request.user.message_set.create(message=msg + ' ' + _("You may edit it again below.")) - if request.POST.has_key("_popup"): - post_url_continue += "?_popup=1" - return HttpResponseRedirect(post_url_continue % pk_value) - if request.POST.has_key("_popup"): - if type(pk_value) is str: # Quote if string, so JavaScript doesn't think it's a variable. - pk_value = '"%s"' % pk_value.replace('"', '\\"') - return HttpResponse('' % \ - (pk_value, str(new_object).replace('"', '\\"'))) - elif request.POST.has_key("_addanother"): - request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name)) - return HttpResponseRedirect(request.path) - else: - request.user.message_set.create(message=msg) - return HttpResponseRedirect(post_url) - else: - # Add default data. - new_data = manipulator.flatten_data() - - # Override the defaults with GET params, if they exist. - new_data.update(dict(request.GET.items())) - - errors = {} - - # Populate the FormWrapper. - form = oldforms.FormWrapper(manipulator, new_data, errors) - - c = template.RequestContext(request, { - 'title': _('Add %s') % opts.verbose_name, - 'form': form, - 'is_popup': request.REQUEST.has_key('_popup'), - 'show_delete': show_delete, - }) - - if object_id_override is not None: - c['object_id'] = object_id_override - - return render_change_form(model, manipulator, c, add=True) - - def change_view(self, request, object_id): - "The 'change' admin view for this model." - model = self.model - opts = model._meta - app_label = opts.app_label - - if not self.has_change_permission(request, object_id): - raise PermissionDenied - - if request.POST and request.POST.has_key("_saveasnew"): - return self.add_view(request, form_url='../../add/') - - try: - manipulator = model.ChangeManipulator(object_id) - except model.DoesNotExist: - raise Http404('%s object with primary key %r does not exist' % (model_name, escape(object_id))) - - if request.POST: - new_data = request.POST.copy() - - if opts.has_field_type(models.FileField): - new_data.update(request.FILES) - - errors = manipulator.get_validation_errors(new_data) - manipulator.do_html2python(new_data) - - if not errors: - new_object = manipulator.save(new_data) - pk_value = new_object._get_pk_val() - - # Construct the change message. - change_message = [] - if manipulator.fields_added: - change_message.append(_('Added %s.') % get_text_list(manipulator.fields_added, _('and'))) - if manipulator.fields_changed: - change_message.append(_('Changed %s.') % get_text_list(manipulator.fields_changed, _('and'))) - if manipulator.fields_deleted: - change_message.append(_('Deleted %s.') % get_text_list(manipulator.fields_deleted, _('and'))) - change_message = ' '.join(change_message) - if not change_message: - change_message = _('No fields changed.') - LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, str(new_object), CHANGE, change_message) - - msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object} - if request.POST.has_key("_continue"): - request.user.message_set.create(message=msg + ' ' + _("You may edit it again below.")) - if request.REQUEST.has_key('_popup'): - return HttpResponseRedirect(request.path + "?_popup=1") - else: - return HttpResponseRedirect(request.path) - elif request.POST.has_key("_saveasnew"): - request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object}) - return HttpResponseRedirect("../%s/" % pk_value) - elif request.POST.has_key("_addanother"): - request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name)) - return HttpResponseRedirect("../add/") - else: - request.user.message_set.create(message=msg) - return HttpResponseRedirect("../") - else: - # Populate new_data with a "flattened" version of the current data. - new_data = manipulator.flatten_data() - - # TODO: do this in flatten_data... - # If the object has ordered objects on its admin page, get the existing - # order and flatten it into a comma-separated list of IDs. - id_order_list = [] - for rel_obj in opts.get_ordered_objects(): - id_order_list.extend(getattr(manipulator.original_object, 'get_%s_order' % rel_obj.object_name.lower())()) - if id_order_list: - new_data['order_'] = ','.join(map(str, id_order_list)) - errors = {} - - # Populate the FormWrapper. - form = oldforms.FormWrapper(manipulator, new_data, errors) - form.original = manipulator.original_object - form.order_objects = [] - - # TODO: Should be done in flatten_data / FormWrapper construction - for related in opts.get_followed_related_objects(): - wrt = related.opts.order_with_respect_to - if wrt and wrt.rel and wrt.rel.to == opts: - func = getattr(manipulator.original_object, 'get_%s_list' % - related.get_accessor_name()) - orig_list = func() - form.order_objects.extend(orig_list) - - c = template.RequestContext(request, { - 'title': _('Change %s') % opts.verbose_name, - 'form': form, - 'object_id': object_id, - 'original': manipulator.original_object, - 'is_popup': request.REQUEST.has_key('_popup'), - }) - return render_change_form(model, manipulator, c, change=True) - - def change_list_view(self, request): - "The 'change list' admin view for this model." - opts = self.model._meta - app_label = opts.app_label - if not self.has_change_permission(request, None): - raise PermissionDenied - try: - cl = ChangeList(request, self.model) - except IncorrectLookupParameters: - # Wacky lookup parameters were given, so redirect to the main - # changelist page, without parameters, and pass an 'invalid=1' - # parameter via the query string. If wacky parameters were given and - # the 'invalid=1' parameter was already in the query string, something - # is screwed up with the database, so display an error page. - if ERROR_FLAG in request.GET.keys(): - return render_to_response('admin/invalid_setup.html', {'title': _('Database error')}) - return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1') - c = template.RequestContext(request, { - 'title': cl.title, - 'is_popup': cl.is_popup, - 'cl': cl, - }) - c.update({'has_add_permission': c['perms'][app_label][opts.get_add_permission()]}), - return render_to_response(['admin/%s/%s/change_list.html' % (app_label, opts.object_name.lower()), - 'admin/%s/change_list.html' % app_label, - 'admin/change_list.html'], context_instance=c) - - def delete_view(self, request, object_id): - "The 'delete' admin view for this model." - opts = self.model._meta - app_label = opts.app_label - if not self.has_delete_permission(request, object_id): - raise PermissionDenied - obj = get_object_or_404(self.model, pk=object_id) - - # Populate deleted_objects, a data structure of all related objects that - # will also be deleted. - deleted_objects = ['%s: %s' % (capfirst(opts.verbose_name), object_id, escape(str(obj))), []] - perms_needed = sets.Set() - _get_deleted_objects(deleted_objects, perms_needed, request.user, obj, opts, 1) - - if request.POST: # The user has already confirmed the deletion. - if perms_needed: - raise PermissionDenied - obj_display = str(obj) - obj.delete() - LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, object_id, obj_display, DELETION) - request.user.message_set.create(message=_('The %(name)s "%(obj)s" was deleted successfully.') % {'name': opts.verbose_name, 'obj': obj_display}) - return HttpResponseRedirect("../../") - extra_context = { - "title": _("Are you sure?"), - "object_name": opts.verbose_name, - "object": obj, - "deleted_objects": deleted_objects, - "perms_lacking": perms_needed, - "opts": opts, - } - return render_to_response(["admin/%s/%s/delete_confirmation.html" % (app_label, opts.object_name.lower() ), - "admin/%s/delete_confirmation.html" % app_label , - "admin/delete_confirmation.html"], extra_context, context_instance=template.RequestContext(request)) - - def history_view(self, request, object_id): - "The 'history' admin view for this model." - model = self.model - opts = model._meta - action_list = LogEntry.objects.filter(object_id=object_id, - content_type__id__exact=ContentType.objects.get_for_model(model).id).select_related().order_by('action_time') - # If no history was found, see whether this object even exists. - obj = get_object_or_404(model, pk=object_id) - extra_context = { - 'title': _('Change history: %s') % obj, - 'action_list': action_list, - 'module_name': capfirst(opts.verbose_name_plural), - 'object': obj, - } - template_list = [ - "admin/%s/%s/object_history.html" % (opts.app_label, opts.object_name.lower()), - "admin/%s/object_history.html" % opts.app_label, - "admin/object_history.html" - ] - return render_to_response(template_list, extra_context, context_instance=template.RequestContext(request)) - class AdminBoundField(object): def __init__(self, field, field_mapping, original): self.field = field