Loading django/contrib/contenttypes/views.py +4 −2 Original line number Diff line number Diff line Loading @@ -63,9 +63,11 @@ def shortcut(request, content_type_id, object_id): for field in obj._meta.fields: if field.remote_field and field.remote_field.model is Site: try: object_domain = getattr(obj, field.name).domain site = getattr(obj, field.name) except Site.DoesNotExist: pass continue if site is not None: object_domain = site.domain if object_domain is not None: break Loading tests/contenttypes_tests/models.py +22 −0 Original line number Diff line number Diff line Loading @@ -4,11 +4,21 @@ from django.contrib.contenttypes.fields import ( GenericForeignKey, GenericRelation, ) from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import SiteManager from django.db import models from django.utils.encoding import python_2_unicode_compatible from django.utils.http import urlquote @python_2_unicode_compatible class Site(models.Model): domain = models.CharField(max_length=100) objects = SiteManager() def __str__(self): return self.domain @python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=100) Loading Loading @@ -115,3 +125,15 @@ class Post(models.Model): def __str__(self): return self.title @python_2_unicode_compatible class ModelWithNullFKToSite(models.Model): title = models.CharField(max_length=200) site = models.ForeignKey(Site, null=True, on_delete=models.CASCADE) def __str__(self): return self.title def get_absolute_url(self): return '/title/%s/' % urlquote(self.title) tests/contenttypes_tests/tests.py +20 −2 Original line number Diff line number Diff line Loading @@ -12,11 +12,14 @@ from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import Site from django.core import checks from django.db import connections, models from django.test import SimpleTestCase, TestCase, override_settings from django.test import SimpleTestCase, TestCase, mock, override_settings from django.test.utils import captured_stdout, isolate_apps from django.utils.encoding import force_str, force_text from .models import Article, Author, SchemeIncludedURL from .models import ( Article, Author, ModelWithNullFKToSite, SchemeIncludedURL, Site as MockSite, ) @override_settings(ROOT_URLCONF='contenttypes_tests.urls') Loading Loading @@ -94,6 +97,21 @@ class ContentTypesViewsTests(TestCase): response = self.client.get(short_url) self.assertEqual(response.status_code, 404) @mock.patch('django.apps.apps.get_model') def test_shortcut_view_with_null_site_fk(self, get_model): """ The shortcut view works if a model's ForeignKey to site is None. """ get_model.side_effect = lambda *args, **kwargs: MockSite if args[0] == 'sites.Site' else ModelWithNullFKToSite obj = ModelWithNullFKToSite.objects.create(title='title') url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(ModelWithNullFKToSite).id, obj.pk) response = self.client.get(url) self.assertRedirects( response, '%s' % obj.get_absolute_url(), fetch_redirect_response=False, ) def test_create_contenttype_on_the_spot(self): """ Make sure ContentTypeManager.get_for_model creates the corresponding Loading Loading
django/contrib/contenttypes/views.py +4 −2 Original line number Diff line number Diff line Loading @@ -63,9 +63,11 @@ def shortcut(request, content_type_id, object_id): for field in obj._meta.fields: if field.remote_field and field.remote_field.model is Site: try: object_domain = getattr(obj, field.name).domain site = getattr(obj, field.name) except Site.DoesNotExist: pass continue if site is not None: object_domain = site.domain if object_domain is not None: break Loading
tests/contenttypes_tests/models.py +22 −0 Original line number Diff line number Diff line Loading @@ -4,11 +4,21 @@ from django.contrib.contenttypes.fields import ( GenericForeignKey, GenericRelation, ) from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import SiteManager from django.db import models from django.utils.encoding import python_2_unicode_compatible from django.utils.http import urlquote @python_2_unicode_compatible class Site(models.Model): domain = models.CharField(max_length=100) objects = SiteManager() def __str__(self): return self.domain @python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=100) Loading Loading @@ -115,3 +125,15 @@ class Post(models.Model): def __str__(self): return self.title @python_2_unicode_compatible class ModelWithNullFKToSite(models.Model): title = models.CharField(max_length=200) site = models.ForeignKey(Site, null=True, on_delete=models.CASCADE) def __str__(self): return self.title def get_absolute_url(self): return '/title/%s/' % urlquote(self.title)
tests/contenttypes_tests/tests.py +20 −2 Original line number Diff line number Diff line Loading @@ -12,11 +12,14 @@ from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import Site from django.core import checks from django.db import connections, models from django.test import SimpleTestCase, TestCase, override_settings from django.test import SimpleTestCase, TestCase, mock, override_settings from django.test.utils import captured_stdout, isolate_apps from django.utils.encoding import force_str, force_text from .models import Article, Author, SchemeIncludedURL from .models import ( Article, Author, ModelWithNullFKToSite, SchemeIncludedURL, Site as MockSite, ) @override_settings(ROOT_URLCONF='contenttypes_tests.urls') Loading Loading @@ -94,6 +97,21 @@ class ContentTypesViewsTests(TestCase): response = self.client.get(short_url) self.assertEqual(response.status_code, 404) @mock.patch('django.apps.apps.get_model') def test_shortcut_view_with_null_site_fk(self, get_model): """ The shortcut view works if a model's ForeignKey to site is None. """ get_model.side_effect = lambda *args, **kwargs: MockSite if args[0] == 'sites.Site' else ModelWithNullFKToSite obj = ModelWithNullFKToSite.objects.create(title='title') url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(ModelWithNullFKToSite).id, obj.pk) response = self.client.get(url) self.assertRedirects( response, '%s' % obj.get_absolute_url(), fetch_redirect_response=False, ) def test_create_contenttype_on_the_spot(self): """ Make sure ContentTypeManager.get_for_model creates the corresponding Loading