Fixed #26085 -- Fixed contenttypes shortcut() view crash with a null fk to Site.
Thanks Fabien Schwob for the initial patch.
This commit is contained in:
parent
e494b9ffb6
commit
d29d11b026
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
@ -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)
|
||||
|
|
|
@ -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')
|
||||
|
@ -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…
Reference in New Issue