mirror of https://github.com/django/django.git
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
This commit is contained in:
parent
88baf06c3d
commit
6ba6489662
|
@ -262,16 +262,9 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
super(ModelAdmin, self).__init__()
|
super(ModelAdmin, self).__init__()
|
||||||
|
|
||||||
def __call__(self, request, url):
|
def __call__(self, request, url):
|
||||||
# Check that LogEntry, ContentType and the auth context processor are installed.
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
from django.contrib.admin.models import LogEntry
|
self.check_dependancies()
|
||||||
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.
|
# Delegate to the appropriate method, based on the URL.
|
||||||
if url is None:
|
if url is None:
|
||||||
|
@ -285,6 +278,23 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
else:
|
else:
|
||||||
return self.change_view(request, unquote(url))
|
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):
|
def _media(self):
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
@ -360,71 +370,59 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
for inline in self.inline_instances:
|
for inline in self.inline_instances:
|
||||||
yield inline.get_formset(request, obj)
|
yield inline.get_formset(request, obj)
|
||||||
|
|
||||||
def save_add(self, request, form, formsets, post_url_continue):
|
def log_addition(self, request, object):
|
||||||
"""
|
"""
|
||||||
Saves the object in the "add" stage and returns an HttpResponseRedirect.
|
Log that an object has been successfully added.
|
||||||
|
|
||||||
`form` is a bound Form instance that's verified to be valid.
|
The default implementation creates an admin LogEntry object.
|
||||||
"""
|
"""
|
||||||
from django.contrib.admin.models import LogEntry, ADDITION
|
from django.contrib.admin.models import LogEntry, ADDITION
|
||||||
opts = self.model._meta
|
LogEntry.objects.log_action(
|
||||||
new_object = form.save(commit=True)
|
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
|
||||||
|
)
|
||||||
|
|
||||||
if formsets:
|
def log_change(self, request, object, message):
|
||||||
for formset in formsets:
|
|
||||||
# HACK: it seems like the parent obejct should be passed into
|
|
||||||
# a method of something, not just set as an attribute
|
|
||||||
formset.instance = new_object
|
|
||||||
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)
|
|
||||||
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."))
|
|
||||||
if request.POST.has_key("_popup"):
|
|
||||||
post_url_continue += "?_popup=1"
|
|
||||||
return HttpResponseRedirect(post_url_continue % pk_value)
|
|
||||||
|
|
||||||
if request.POST.has_key("_popup"):
|
|
||||||
return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \
|
|
||||||
# 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)))
|
|
||||||
return HttpResponseRedirect(request.path)
|
|
||||||
else:
|
|
||||||
request.user.message_set.create(message=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.
|
|
||||||
if self.has_change_permission(request, None):
|
|
||||||
post_url = '../'
|
|
||||||
else:
|
|
||||||
post_url = '../../../'
|
|
||||||
return HttpResponseRedirect(post_url)
|
|
||||||
save_add = transaction.commit_on_success(save_add)
|
|
||||||
|
|
||||||
def save_change(self, request, form, formsets=None):
|
|
||||||
"""
|
"""
|
||||||
Saves the object in the "change" stage and returns an HttpResponseRedirect.
|
Log that an object has been successfully changed.
|
||||||
|
|
||||||
`form` is a bound Form instance that's verified to be valid.
|
The default implementation creates an admin LogEntry object.
|
||||||
|
|
||||||
`formsets` is a sequence of InlineFormSet instances that are verified to be valid.
|
|
||||||
"""
|
"""
|
||||||
from django.contrib.admin.models import LogEntry, CHANGE
|
from django.contrib.admin.models import LogEntry, CHANGE
|
||||||
opts = self.model._meta
|
LogEntry.objects.log_action(
|
||||||
new_object = form.save(commit=True)
|
user_id = request.user.pk,
|
||||||
pk_value = new_object._get_pk_val()
|
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
|
||||||
|
)
|
||||||
|
|
||||||
if formsets:
|
def log_deletion(self, request, object, object_repr):
|
||||||
for formset in formsets:
|
"""
|
||||||
formset.save()
|
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.
|
||||||
|
|
||||||
# Construct the change message.
|
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 = []
|
change_message = []
|
||||||
if form.changed_data:
|
if form.changed_data:
|
||||||
change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
|
change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
|
||||||
|
@ -445,25 +443,98 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
% {'name': deleted_object._meta.verbose_name,
|
% {'name': deleted_object._meta.verbose_name,
|
||||||
'object': deleted_object})
|
'object': deleted_object})
|
||||||
change_message = ' '.join(change_message)
|
change_message = ' '.join(change_message)
|
||||||
if not change_message:
|
return change_message or _('No fields changed.')
|
||||||
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)
|
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):
|
||||||
|
"""
|
||||||
|
Saves the object in the "add" stage and returns an HttpResponseRedirect.
|
||||||
|
|
||||||
|
`form` is a bound Form instance that's verified to be valid.
|
||||||
|
"""
|
||||||
|
opts = self.model._meta
|
||||||
|
new_object = form.save(commit=True)
|
||||||
|
|
||||||
|
if formsets:
|
||||||
|
for formset in formsets:
|
||||||
|
# HACK: it seems like the parent obejct should be passed into
|
||||||
|
# a method of something, not just set as an attribute
|
||||||
|
formset.instance = new_object
|
||||||
|
formset.save()
|
||||||
|
|
||||||
|
pk_value = new_object._get_pk_val()
|
||||||
|
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"):
|
||||||
|
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)
|
||||||
|
|
||||||
|
if request.POST.has_key("_popup"):
|
||||||
|
return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \
|
||||||
|
# escape() calls force_unicode.
|
||||||
|
(escape(pk_value), escape(new_object)))
|
||||||
|
elif request.POST.has_key("_addanother"):
|
||||||
|
self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
|
||||||
|
return HttpResponseRedirect(request.path)
|
||||||
|
else:
|
||||||
|
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.
|
||||||
|
if self.has_change_permission(request, None):
|
||||||
|
post_url = '../'
|
||||||
|
else:
|
||||||
|
post_url = '../../../'
|
||||||
|
return HttpResponseRedirect(post_url)
|
||||||
|
save_add = transaction.commit_on_success(save_add)
|
||||||
|
|
||||||
|
def save_change(self, request, form, formsets=None):
|
||||||
|
"""
|
||||||
|
Saves the object in the "change" stage and returns an HttpResponseRedirect.
|
||||||
|
|
||||||
|
`form` is a bound Form instance that's verified to be valid.
|
||||||
|
|
||||||
|
`formsets` is a sequence of InlineFormSet instances that are verified to be valid.
|
||||||
|
"""
|
||||||
|
opts = self.model._meta
|
||||||
|
new_object = form.save(commit=True)
|
||||||
|
pk_value = new_object._get_pk_val()
|
||||||
|
|
||||||
|
if formsets:
|
||||||
|
for formset in formsets:
|
||||||
|
formset.save()
|
||||||
|
|
||||||
|
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)}
|
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"):
|
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'):
|
if request.REQUEST.has_key('_popup'):
|
||||||
return HttpResponseRedirect(request.path + "?_popup=1")
|
return HttpResponseRedirect(request.path + "?_popup=1")
|
||||||
else:
|
else:
|
||||||
return HttpResponseRedirect(request.path)
|
return HttpResponseRedirect(request.path)
|
||||||
elif request.POST.has_key("_saveasnew"):
|
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)
|
return HttpResponseRedirect("../%s/" % pk_value)
|
||||||
elif request.POST.has_key("_addanother"):
|
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/")
|
return HttpResponseRedirect("../add/")
|
||||||
else:
|
else:
|
||||||
request.user.message_set.create(message=msg)
|
self.message_user(request, msg)
|
||||||
return HttpResponseRedirect("../")
|
return HttpResponseRedirect("../")
|
||||||
save_change = transaction.commit_on_success(save_change)
|
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):
|
def delete_view(self, request, object_id, extra_context=None):
|
||||||
"The 'delete' admin view for this model."
|
"The 'delete' admin view for this model."
|
||||||
from django.contrib.admin.models import LogEntry, DELETION
|
|
||||||
opts = self.model._meta
|
opts = self.model._meta
|
||||||
app_label = opts.app_label
|
app_label = opts.app_label
|
||||||
|
|
||||||
|
@ -678,8 +748,10 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
obj_display = str(obj)
|
obj_display = str(obj)
|
||||||
obj.delete()
|
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):
|
if not self.has_change_permission(request, None):
|
||||||
return HttpResponseRedirect("../../../../")
|
return HttpResponseRedirect("../../../../")
|
||||||
return HttpResponseRedirect("../../")
|
return HttpResponseRedirect("../../")
|
||||||
|
|
Loading…
Reference in New Issue