Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
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
@jacobian jacobian authored
Showing with 118 additions and 46 deletions.
  1. +118 −46 django/contrib/admin/options.py
View
164 django/contrib/admin/options.py
@@ -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.