Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Broke the admin's use of LogEntry and user messages out into callback…

…s on ModelAdmin. Refs #6002.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8265 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 6ba64896622213ce44ace2c605e4eaafed1e9fc5 1 parent 88baf06
Jacob Kaplan-Moss jacobian authored
Showing with 118 additions and 46 deletions.
  1. +118 −46 django/contrib/admin/options.py
164 django/contrib/admin/options.py
View
@@ -262,16 +262,9 @@ def __init__(self, model, admin_site):
super(ModelAdmin, self).__init__()
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.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.")
+ self.check_dependancies()
# Delegate to the appropriate method, based on the URL.
if url is None:
@@ -285,6 +278,23 @@ def __call__(self, request, url):
else:
return self.change_view(request, unquote(url))
+ def check_dependancies(self):
+ """
+ Check that all things needed to run the admin have been correctly installed.
+
+ The default implementation checks that LogEntry, ContentType and the
+ auth context processor are installed.
+ """
+ from django.conf import settings
+ 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.")
+
def _media(self):
from django.conf import settings
@@ -359,6 +369,88 @@ def get_form(self, request, obj=None):
def get_formsets(self, request, obj=None):
for inline in self.inline_instances:
yield inline.get_formset(request, obj)
+
+ def log_addition(self, request, object):
+ """
+ Log that an object has been successfully added.
+
+ The default implementation creates an admin LogEntry object.
+ """
+ from django.contrib.admin.models import LogEntry, ADDITION
+ LogEntry.objects.log_action(
+ user_id = request.user.pk,
+ content_type_id = ContentType.objects.get_for_model(object).pk,
+ object_id = object.pk,
+ object_repr = force_unicode(object),
+ action_flag = ADDITION
+ )
+
+ def log_change(self, request, object, message):
+ """
+ Log that an object has been successfully changed.
+
+ The default implementation creates an admin LogEntry object.
+ """
+ from django.contrib.admin.models import LogEntry, CHANGE
+ LogEntry.objects.log_action(
+ user_id = request.user.pk,
+ content_type_id = ContentType.objects.get_for_model(object).pk,
+ object_id = object.pk,
+ object_repr = force_unicode(object),
+ action_flag = CHANGE,
+ change_message = message
+ )
+
+ def log_deletion(self, request, object, object_repr):
+ """
+ Log that an object has been successfully deleted. Note that since the
+ object is deleted, it might no longer be safe to call *any* methods
+ on the object, hence this method getting object_repr.
+
+ The default implementation creates an admin LogEntry object.
+ """
+ from django.contrib.admin.models import LogEntry, DELETION
+ LogEntry.objects.log_action(
+ user_id = request.user.id,
+ content_type_id = ContentType.objects.get_for_model(self.model).pk,
+ object_id = object.pk,
+ object_repr = object_repr,
+ action_flag = DELETION
+ )
+
+
+ def construct_change_message(self, request, form, formsets):
+ """
+ Construct a change message from a changed object.
+ """
+ change_message = []
+ if form.changed_data:
+ change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
+
+ if formsets:
+ for formset in formsets:
+ for added_object in formset.new_objects:
+ change_message.append(_('Added %(name)s "%(object)s".')
+ % {'name': added_object._meta.verbose_name,
+ 'object': added_object})
+ for changed_object, changed_fields in formset.changed_objects:
+ change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
+ % {'list': get_text_list(changed_fields, _('and')),
+ 'name': changed_object._meta.verbose_name,
+ 'object': changed_object})
+ for deleted_object in formset.deleted_objects:
+ change_message.append(_('Deleted %(name)s "%(object)s".')
+ % {'name': deleted_object._meta.verbose_name,
+ 'object': deleted_object})
+ change_message = ' '.join(change_message)
+ return change_message or _('No fields changed.')
+
+ def message_user(self, request, message):
+ """
+ Send a message to the user. The default implementation
+ posts a message using the auth Message object.
+ """
+ request.user.message_set.create(message=message)
def save_add(self, request, form, formsets, post_url_continue):
"""
@@ -366,7 +458,6 @@ def save_add(self, request, form, formsets, post_url_continue):
`form` is a bound Form instance that's verified to be valid.
"""
- from django.contrib.admin.models import LogEntry, ADDITION
opts = self.model._meta
new_object = form.save(commit=True)
@@ -378,12 +469,13 @@ def save_add(self, request, form, formsets, post_url_continue):
formset.save()
pk_value = new_object._get_pk_val()
- LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, pk_value, force_unicode(new_object), ADDITION)
+ self.log_addition(request, new_object)
+
msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(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."))
+ self.message_user(request, 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)
@@ -393,10 +485,11 @@ def save_add(self, request, form, formsets, post_url_continue):
# escape() calls force_unicode.
(escape(pk_value), escape(new_object)))
elif request.POST.has_key("_addanother"):
- request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
+ self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
return HttpResponseRedirect(request.path)
else:
- request.user.message_set.create(message=msg)
+ self.message_user(request, msg)
+
# Figure out where to redirect. If the user has change permission,
# redirect to the change-list page for this object. Otherwise,
# redirect to the admin index.
@@ -415,7 +508,6 @@ def save_change(self, request, form, formsets=None):
`formsets` is a sequence of InlineFormSet instances that are verified to be valid.
"""
- from django.contrib.admin.models import LogEntry, CHANGE
opts = self.model._meta
new_object = form.save(commit=True)
pk_value = new_object._get_pk_val()
@@ -423,47 +515,26 @@ def save_change(self, request, form, formsets=None):
if formsets:
for formset in formsets:
formset.save()
-
- # Construct the change message.
- change_message = []
- if form.changed_data:
- change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
-
- if formsets:
- for formset in formsets:
- for added_object in formset.new_objects:
- change_message.append(_('Added %(name)s "%(object)s".')
- % {'name': added_object._meta.verbose_name,
- 'object': added_object})
- for changed_object, changed_fields in formset.changed_objects:
- change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
- % {'list': get_text_list(changed_fields, _('and')),
- 'name': changed_object._meta.verbose_name,
- 'object': changed_object})
- for deleted_object in formset.deleted_objects:
- change_message.append(_('Deleted %(name)s "%(object)s".')
- % {'name': deleted_object._meta.verbose_name,
- 'object': deleted_object})
- 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(self.model).id, pk_value, force_unicode(new_object), CHANGE, change_message)
+
+ change_message = self.construct_change_message(request, form, formsets)
+ self.log_change(request, new_object, change_message)
msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(new_object)}
if request.POST.has_key("_continue"):
- request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
+ self.message_user(request, 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': force_unicode(opts.verbose_name), 'obj': new_object})
+ msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(opts.verbose_name), 'obj': new_object}
+ self.message_user(request, msg)
return HttpResponseRedirect("../%s/" % pk_value)
elif request.POST.has_key("_addanother"):
- request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
+ self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
return HttpResponseRedirect("../add/")
else:
- request.user.message_set.create(message=msg)
+ self.message_user(request, msg)
return HttpResponseRedirect("../")
save_change = transaction.commit_on_success(save_change)
@@ -649,7 +720,6 @@ def changelist_view(self, request, extra_context=None):
def delete_view(self, request, object_id, extra_context=None):
"The 'delete' admin view for this model."
- from django.contrib.admin.models import LogEntry, DELETION
opts = self.model._meta
app_label = opts.app_label
@@ -678,8 +748,10 @@ def delete_view(self, request, object_id, extra_context=None):
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': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)})
+
+ self.log_deletion(request, obj, obj_display)
+ self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)})
+
if not self.has_change_permission(request, None):
return HttpResponseRedirect("../../../../")
return HttpResponseRedirect("../../")
Please sign in to comment.
Something went wrong with that request. Please try again.