mirror of
https://github.com/django/django.git
synced 2025-04-26 10:14:36 +00:00
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:
|
for field in obj._meta.fields:
|
||||||
if field.remote_field and field.remote_field.model is Site:
|
if field.remote_field and field.remote_field.model is Site:
|
||||||
try:
|
try:
|
||||||
object_domain = getattr(obj, field.name).domain
|
site = getattr(obj, field.name)
|
||||||
except Site.DoesNotExist:
|
except Site.DoesNotExist:
|
||||||
pass
|
continue
|
||||||
|
if site is not None:
|
||||||
|
object_domain = site.domain
|
||||||
if object_domain is not None:
|
if object_domain is not None:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -4,11 +4,21 @@ from django.contrib.contenttypes.fields import (
|
|||||||
GenericForeignKey, GenericRelation,
|
GenericForeignKey, GenericRelation,
|
||||||
)
|
)
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
from django.contrib.sites.models import SiteManager
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
from django.utils.http import urlquote
|
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
|
@python_2_unicode_compatible
|
||||||
class Author(models.Model):
|
class Author(models.Model):
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100)
|
||||||
@ -115,3 +125,15 @@ class Post(models.Model):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.title
|
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.contrib.sites.models import Site
|
||||||
from django.core import checks
|
from django.core import checks
|
||||||
from django.db import connections, models
|
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.test.utils import captured_stdout, isolate_apps
|
||||||
from django.utils.encoding import force_str, force_text
|
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')
|
@override_settings(ROOT_URLCONF='contenttypes_tests.urls')
|
||||||
@ -94,6 +97,21 @@ class ContentTypesViewsTests(TestCase):
|
|||||||
response = self.client.get(short_url)
|
response = self.client.get(short_url)
|
||||||
self.assertEqual(response.status_code, 404)
|
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):
|
def test_create_contenttype_on_the_spot(self):
|
||||||
"""
|
"""
|
||||||
Make sure ContentTypeManager.get_for_model creates the corresponding
|
Make sure ContentTypeManager.get_for_model creates the corresponding
|
||||||
|
Loading…
x
Reference in New Issue
Block a user