diff --git a/django/contrib/admin/templates/admin/change_form.html b/django/contrib/admin/templates/admin/change_form.html index 47cdda31ab..f3a2516934 100644 --- a/django/contrib/admin/templates/admin/change_form.html +++ b/django/contrib/admin/templates/admin/change_form.html @@ -17,7 +17,7 @@ {% block content %}
{% if change %}{% if not is_popup %} {% endif %}{% endif %}
{% block form_top %}{% endblock %} diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 86754b91c7..df80d48a2a 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -2,6 +2,7 @@ from django import forms, template from django.conf import settings from django.contrib.admin.filterspecs import FilterSpec from django.contrib.admin.views.decorators import staff_member_required +from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist, PermissionDenied from django.core.paginator import ObjectPaginator, InvalidPage from django.shortcuts import get_object_or_404, render_to_response @@ -172,6 +173,7 @@ def render_change_form(model, manipulator, context, add=False, change=False, for 'inline_related_objects': inline_related_objects, 'form_url': form_url, 'opts': opts, + 'content_type_id': ContentType.objects.get_for_model(model).id, } context.update(extra_context) return render_to_response([ @@ -205,7 +207,7 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po if not errors: new_object = manipulator.save(new_data) pk_value = new_object._get_pk_val() - LogEntry.objects.log_action(request.user.id, opts.get_content_type_id(), pk_value, str(new_object), ADDITION) + 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. @@ -289,7 +291,7 @@ def change_stage(request, app_label, model_name, object_id): change_message = ' '.join(change_message) if not change_message: change_message = _('No fields changed.') - LogEntry.objects.log_action(request.user.id, opts.get_content_type_id(), pk_value, str(new_object), CHANGE, change_message) + 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"): @@ -451,7 +453,7 @@ def delete_stage(request, app_label, model_name, object_id): raise PermissionDenied obj_display = str(obj) obj.delete() - LogEntry.objects.log_action(request.user.id, opts.get_content_type_id(), object_id, obj_display, DELETION) + LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, object_id, obj_display, DELETION) request.user.message_set.add(message=_('The %(name)s "%(obj)s" was deleted successfully.') % {'name': opts.verbose_name, 'obj': obj_display}) return HttpResponseRedirect("../../") return render_to_response('admin/delete_confirmation', { @@ -468,7 +470,7 @@ def history(request, app_label, model_name, object_id): if model is None: raise Http404, "App %r, model %r, not found" % (app_label, model_name) action_list = LogEntry.objects.filter(object_id=object_id, - content_type__id__exact=model._meta.get_content_type_id()).select_related().order_by('action_time') + 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) return render_to_response('admin/object_history', { diff --git a/django/contrib/contenttypes/models.py b/django/contrib/contenttypes/models.py index 27a7429c7c..2910edabde 100644 --- a/django/contrib/contenttypes/models.py +++ b/django/contrib/contenttypes/models.py @@ -13,10 +13,30 @@ class Package(models.Model): def __repr__(self): return self.name +class ContentTypeManager(models.Manager): + def get_for_model(self, model): + """ + Returns the ContentType object for the given model, creating the + ContentType if necessary. + """ + opts = model._meta + try: + return self.model._default_manager.get(python_module_name__exact=opts.module_name, + package__label__exact=opts.app_label) + except self.model.DoesNotExist: + # The str() is needed around opts.verbose_name because it's a + # django.utils.functional.__proxy__ object. + ct = self.model(name=str(opts.verbose_name), + package=Package.objects.get(label=opts.app_label), + python_module_name=opts.module_name) + ct.save() + return ct + class ContentType(models.Model): name = models.CharField(_('name'), maxlength=100) package = models.ForeignKey(Package, db_column='package') python_module_name = models.CharField(_('python module name'), maxlength=50) + objects = ContentTypeManager() class Meta: verbose_name = _('content type') verbose_name_plural = _('content types') diff --git a/django/db/models/options.py b/django/db/models/options.py index 88051d99c8..541b66bc8f 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -84,15 +84,6 @@ class Options: def __repr__(self): return '' % self.object_name - def get_content_type_id(self): - "Returns the content-type ID for this object type." - if not hasattr(self, '_content_type_id'): - from django.contrib.contenttypes.models import ContentType - self._content_type_id = ContentType.objects.get( - python_module_name__exact=self.module_name, - package__label__exact=self.app_label).id - return self._content_type_id - def get_field(self, name, many_to_many=True): "Returns the requested field by name. Raises FieldDoesNotExist on error." to_search = many_to_many and (self.fields + self.many_to_many) or self.fields