Quellcode durchsuchen

Avoided importing models from django.contrib.admin.

Fixed #21923. Refs #21719.
Aymeric Augustin vor 11 Jahren
Ursprung
Commit
76ff266df1

+ 2 - 2
django/contrib/admin/__init__.py

@@ -2,8 +2,8 @@
 # has been referenced in documentation.
 from django.contrib.admin.decorators import register
 from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
-from django.contrib.admin.options import ModelAdmin, HORIZONTAL, VERTICAL
-from django.contrib.admin.options import StackedInline, TabularInline
+from django.contrib.admin.options import (HORIZONTAL, VERTICAL,
+    ModelAdmin, StackedInline, TabularInline)
 from django.contrib.admin.filters import (ListFilter, SimpleListFilter,
     FieldListFilter, BooleanFieldListFilter, RelatedFieldListFilter,
     ChoicesFieldListFilter, DateFieldListFilter, AllValuesFieldListFilter)

+ 3 - 1
django/contrib/admin/helpers.py

@@ -4,7 +4,6 @@ from django import forms
 from django.contrib.admin.utils import (flatten_fieldsets, lookup_field,
     display_for_field, label_for_field, help_text_for_field)
 from django.contrib.admin.templatetags.admin_static import static
-from django.contrib.contenttypes.models import ContentType
 from django.core.exceptions import ObjectDoesNotExist
 from django.db.models.fields.related import ManyToManyRel
 from django.forms.utils import flatatt
@@ -257,6 +256,9 @@ class InlineAdminForm(AdminForm):
         self.model_admin = model_admin
         self.original = original
         if original is not None:
+            # Since this module gets imported in the application's root package,
+            # it cannot import models from other applications at the module level.
+            from django.contrib.contenttypes.models import ContentType
             self.original_content_type_id = ContentType.objects.get_for_model(original).pk
         self.show_url = original and view_on_site_url is not None
         self.absolute_url = view_on_site_url

+ 13 - 7
django/contrib/admin/options.py

@@ -17,7 +17,6 @@ from django.contrib.admin.utils import (unquote, flatten_fieldsets,
 from django.contrib.admin.templatetags.admin_static import static
 from django.contrib.admin.templatetags.admin_urls import add_preserved_filters
 from django.contrib.auth import get_permission_codename
-from django.contrib.contenttypes.models import ContentType
 from django.core import checks
 from django.core.exceptions import PermissionDenied, ValidationError, FieldError, ImproperlyConfigured
 from django.core.paginator import Paginator
@@ -55,6 +54,13 @@ TO_FIELD_VAR = '_to_field'
 HORIZONTAL, VERTICAL = 1, 2
 
 
+def get_content_type_for_model(obj):
+    # Since this module gets imported in the application's root package,
+    # it cannot import models from other applications at the module level.
+    from django.contrib.contenttypes.models import ContentType
+    return ContentType.objects.get_for_model(obj)
+
+
 def get_ul_class(radio_style):
     return 'radiolist' if radio_style == VERTICAL else 'radiolist inline'
 
@@ -291,7 +297,7 @@ class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)):
         elif self.view_on_site and hasattr(obj, 'get_absolute_url'):
             # use the ContentType lookup if view_on_site is True
             return reverse('admin:view_on_site', kwargs={
-                'content_type_id': ContentType.objects.get_for_model(obj).pk,
+                'content_type_id': get_content_type_for_model(obj).pk,
                 'object_id': obj.pk
             })
 
@@ -728,7 +734,7 @@ class ModelAdmin(BaseModelAdmin):
         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,
+            content_type_id=get_content_type_for_model(object).pk,
             object_id=object.pk,
             object_repr=force_text(object),
             action_flag=ADDITION
@@ -743,7 +749,7 @@ class ModelAdmin(BaseModelAdmin):
         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,
+            content_type_id=get_content_type_for_model(object).pk,
             object_id=object.pk,
             object_repr=force_text(object),
             action_flag=CHANGE,
@@ -760,7 +766,7 @@ class ModelAdmin(BaseModelAdmin):
         from django.contrib.admin.models import LogEntry, DELETION
         LogEntry.objects.log_action(
             user_id=request.user.pk,
-            content_type_id=ContentType.objects.get_for_model(self.model).pk,
+            content_type_id=get_content_type_for_model(self.model).pk,
             object_id=object.pk,
             object_repr=object_repr,
             action_flag=DELETION
@@ -1042,7 +1048,7 @@ class ModelAdmin(BaseModelAdmin):
             'absolute_url': view_on_site_url,
             'form_url': form_url,
             'opts': opts,
-            'content_type_id': ContentType.objects.get_for_model(self.model).id,
+            'content_type_id': get_content_type_for_model(self.model).pk,
             'save_as': self.save_as,
             'save_on_top': self.save_on_top,
             'to_field_var': TO_FIELD_VAR,
@@ -1660,7 +1666,7 @@ class ModelAdmin(BaseModelAdmin):
         app_label = opts.app_label
         action_list = LogEntry.objects.filter(
             object_id=unquote(object_id),
-            content_type=ContentType.objects.get_for_model(model)
+            content_type=get_content_type_for_model(model)
         ).select_related().order_by('action_time')
 
         context = dict(self.admin_site.each_context(),

+ 8 - 2
django/contrib/admin/sites.py

@@ -1,9 +1,7 @@
 from functools import update_wrapper
 from django.http import Http404, HttpResponseRedirect
 from django.contrib.admin import ModelAdmin, actions
-from django.contrib.admin.forms import AdminAuthenticationForm
 from django.contrib.auth import logout as auth_logout, REDIRECT_FIELD_NAME
-from django.contrib.contenttypes import views as contenttype_views
 from django.views.decorators.csrf import csrf_protect
 from django.db.models.base import ModelBase
 from django.apps import apps
@@ -212,6 +210,10 @@ class AdminSite(object):
 
     def get_urls(self):
         from django.conf.urls import patterns, url, include
+        # Since this module gets imported in the application's root package,
+        # it cannot import models from other applications at the module level,
+        # and django.contrib.contenttypes.views imports ContentType.
+        from django.contrib.contenttypes import views as contenttype_views
 
         if settings.DEBUG:
             self.check_dependencies()
@@ -327,6 +329,10 @@ class AdminSite(object):
         Displays the login form for the given HttpRequest.
         """
         from django.contrib.auth.views import login
+        # Since this module gets imported in the application's root package,
+        # it cannot import models from other applications at the module level,
+        # and django.contrib.admin.forms eventually imports User.
+        from django.contrib.admin.forms import AdminAuthenticationForm
         context = dict(self.each_context(),
             title=_('Log in'),
             app_path=request.get_full_path(),