1
0
mirror of https://github.com/django/django.git synced 2025-07-05 18:29:11 +00:00

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
This commit is contained in:
Adrian Holovaty 2007-01-15 01:53:11 +00:00
parent 40256823fd
commit 28990ef07b
2 changed files with 352 additions and 328 deletions

View File

@ -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('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \
(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: <a href="../../%s/">%s</a>' % (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))

View File

@ -1,26 +1,18 @@
from django import oldforms, template from django import template
from django.conf import settings
from django.contrib.admin.filterspecs import FilterSpec 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.contrib.admin.views.decorators import staff_member_required
from django.views.decorators.cache import never_cache from django.views.decorators.cache import never_cache
from django.contrib.contenttypes.models import ContentType 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.core.paginator import ObjectPaginator, InvalidPage
from django.shortcuts import get_object_or_404, render_to_response from django.shortcuts import get_object_or_404, render_to_response
from django.db import models from django.db import models
from django.db.models.query import handle_legacy_orderlist, QuerySet 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.html import escape
from django.utils.text import capfirst, get_text_list from django.utils.text import capfirst
import operator 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 # 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. # 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 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): def quote(s):
""" """
Ensure that primary key values do not confuse the admin URLs by escaping 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) res[i] = '_%02X' % ord(c)
return ''.join(res) 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): def get_javascript_imports(opts, auto_populated_fields, field_sets):
# Put in any necessary JavaScript imports. # Put in any necessary JavaScript imports.
js = ['js/core.js', 'js/admin/RelatedObjectLookups.js'] 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)) raise Http404("App %r, model %r, not found" % (app_label, model_name))
if not model._meta.admin: if not model._meta.admin:
raise Http404("This object has no admin interface.") raise Http404("This object has no admin interface.")
mav = ModelAdminView(model) mav = ModelAdmin(model)
return mav(request, rest_of_url) return mav(request, rest_of_url)
model_admin_view = staff_member_required(never_cache(model_admin_view)) 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('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \
(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: <a href="../../%s/">%s</a>' % (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): class AdminBoundField(object):
def __init__(self, field, field_mapping, original): def __init__(self, field, field_mapping, original):
self.field = field self.field = field