diff options
| author | Jacob Kaplan-Moss <jacob@jacobian.org> | 2008-08-09 16:45:15 +0000 |
|---|---|---|
| committer | Jacob Kaplan-Moss <jacob@jacobian.org> | 2008-08-09 16:45:15 +0000 |
| commit | 6ba64896622213ce44ace2c605e4eaafed1e9fc5 (patch) | |
| tree | bd132454a504a28900acc42d56452931f7b54074 | |
| parent | 88baf06c3d7334e39273c22bffa2f80db4d71d58 (diff) | |
Broke the admin's use of LogEntry and user messages out into callbacks on ModelAdmin. Refs #6002.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8265 bcc190cf-cafb-0310-a4f2-bffc1f526a37
| -rw-r--r-- | django/contrib/admin/options.py | 164 |
1 files changed, 118 insertions, 46 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 364a1b9852..70a1b563b8 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -262,16 +262,9 @@ class ModelAdmin(BaseModelAdmin): 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 @@ class ModelAdmin(BaseModelAdmin): 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 @@ class ModelAdmin(BaseModelAdmin): 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 @@ class ModelAdmin(BaseModelAdmin): `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 @@ class ModelAdmin(BaseModelAdmin): 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 @@ class ModelAdmin(BaseModelAdmin): # 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 @@ class ModelAdmin(BaseModelAdmin): `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 @@ class ModelAdmin(BaseModelAdmin): 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 @@ class ModelAdmin(BaseModelAdmin): 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 @@ class ModelAdmin(BaseModelAdmin): 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("../../") |
