Deprecated django.views.defaults.shortcut.

This commit is contained in:
Aymeric Augustin 2013-03-14 20:28:24 +01:00
parent 2f121dfe63
commit 3f2befc931
12 changed files with 156 additions and 46 deletions

View File

@ -1,5 +1,10 @@
import warnings
from django.conf.urls import patterns from django.conf.urls import patterns
warnings.warn("django.conf.urls.shortcut will be removed in Django 1.8.",
PendingDeprecationWarning)
urlpatterns = patterns('django.views', urlpatterns = patterns('django.views',
(r'^(?P<content_type_id>\d+)/(?P<object_id>.*)/$', 'defaults.shortcut'), (r'^(?P<content_type_id>\d+)/(?P<object_id>.*)/$', 'defaults.shortcut'),
) )

View File

@ -1,3 +1,5 @@
import warnings
from django import http from django import http
from django.template import (Context, RequestContext, from django.template import (Context, RequestContext,
loader, Template, TemplateDoesNotExist) loader, Template, TemplateDoesNotExist)
@ -63,12 +65,9 @@ def permission_denied(request, template_name='403.html'):
def shortcut(request, content_type_id, object_id): def shortcut(request, content_type_id, object_id):
# TODO: Remove this in Django 2.0. warnings.warn(
# This is a legacy view that depends on the contenttypes framework. "django.views.defaults.shortcut will be removed in Django 1.8. "
# The core logic was moved to django.contrib.contenttypes.views after "Import it from django.contrib.contenttypes.views instead.",
# Django 1.0, but this remains here for backwards compatibility. PendingDeprecationWarning, stacklevel=2)
# Note that the import is *within* this function, rather than being at
# module level, because we don't want to assume people have contenttypes
# installed.
from django.contrib.contenttypes.views import shortcut as real_shortcut from django.contrib.contenttypes.views import shortcut as real_shortcut
return real_shortcut(request, content_type_id, object_id) return real_shortcut(request, content_type_id, object_id)

View File

@ -362,6 +362,9 @@ these changes.
* Remove the backward compatible shims introduced to rename the attributes * Remove the backward compatible shims introduced to rename the attributes
``ChangeList.root_query_set`` and ``ChangeList.query_set``. ``ChangeList.root_query_set`` and ``ChangeList.query_set``.
* ``django.conf.urls.shortcut`` and ``django.views.defaults.shortcut`` will be
removed.
* The following private APIs will be removed: * The following private APIs will be removed:
- ``django.db.close_connection()`` - ``django.db.close_connection()``

View File

@ -352,3 +352,20 @@ private API, it will go through a regular deprecation path.
Methods that return a ``QuerySet`` such as ``Manager.get_query_set`` or Methods that return a ``QuerySet`` such as ``Manager.get_query_set`` or
``ModelAdmin.queryset`` have been renamed to ``get_queryset``. ``ModelAdmin.queryset`` have been renamed to ``get_queryset``.
``shortcut`` view and URLconf
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``shortcut`` view was moved from ``django.views.defaults`` to
``django.contrib.contentypes.views`` shortly after the 1.0 release, but the
old location was never deprecated. This oversight was corrected in Django 1.6
and you should now use the new location.
The URLconf ``django.conf.urls.shortcut`` was also deprecated. If you're
including it in an URLconf, simply replace::
(r'^prefix/', include('django.conf.urls.shortcut')),
with::
(r'^prefix/(?P<content_type_id>\d+)/(?P<object_id>.*)/$', 'django.contrib.contentypes.views'),

View File

@ -330,7 +330,6 @@ itself. It includes a number of other URLconfs::
(r'^comments/', include('django.contrib.comments.urls')), (r'^comments/', include('django.contrib.comments.urls')),
(r'^community/', include('django_website.aggregator.urls')), (r'^community/', include('django_website.aggregator.urls')),
(r'^contact/', include('django_website.contact.urls')), (r'^contact/', include('django_website.contact.urls')),
(r'^r/', include('django.conf.urls.shortcut')),
# ... snip ... # ... snip ...
) )

View File

View File

@ -0,0 +1,47 @@
[
{
"pk": 1,
"model": "contenttypes_tests.author",
"fields": {
"name": "Boris"
}
},
{
"pk": 1,
"model": "contenttypes_tests.article",
"fields": {
"author": 1,
"title": "Old Article",
"slug": "old_article",
"date_created": "2001-01-01 21:22:23"
}
},
{
"pk": 2,
"model": "contenttypes_tests.article",
"fields": {
"author": 1,
"title": "Current Article",
"slug": "current_article",
"date_created": "2007-09-17 21:22:23"
}
},
{
"pk": 3,
"model": "contenttypes_tests.article",
"fields": {
"author": 1,
"title": "Future Article",
"slug": "future_article",
"date_created": "3000-01-01 21:22:23"
}
},
{
"pk": 1,
"model": "sites.site",
"fields": {
"domain": "testserver",
"name": "testserver"
}
}
]

View File

@ -0,0 +1,24 @@
from __future__ import absolute_import, unicode_literals
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible
class Author(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
def get_absolute_url(self):
return '/views/authors/%s/' % self.id
@python_2_unicode_compatible
class Article(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField()
author = models.ForeignKey(Author)
date_created = models.DateTimeField()
def __str__(self):
return self.title

View File

@ -0,0 +1,47 @@
from __future__ import absolute_import, unicode_literals
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase
from .models import Author, Article
class ContentTypesViewsTests(TestCase):
fixtures = ['testdata.json']
urls = 'contenttypes_tests.urls'
def test_shortcut_with_absolute_url(self):
"Can view a shortcut for an Author object that has a get_absolute_url method"
for obj in Author.objects.all():
short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Author).id, obj.pk)
response = self.client.get(short_url)
self.assertRedirects(response, 'http://testserver%s' % obj.get_absolute_url(),
status_code=302, target_status_code=404)
def test_shortcut_no_absolute_url(self):
"Shortcuts for an object that has no get_absolute_url method raises 404"
for obj in Article.objects.all():
short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Article).id, obj.pk)
response = self.client.get(short_url)
self.assertEqual(response.status_code, 404)
def test_wrong_type_pk(self):
short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Author).id, 'nobody/expects')
response = self.client.get(short_url)
self.assertEqual(response.status_code, 404)
def test_shortcut_bad_pk(self):
short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Author).id, '42424242')
response = self.client.get(short_url)
self.assertEqual(response.status_code, 404)
def test_nonint_content_type(self):
an_author = Author.objects.all()[0]
short_url = '/shortcut/%s/%s/' % ('spam', an_author.pk)
response = self.client.get(short_url)
self.assertEqual(response.status_code, 404)
def test_bad_content_type(self):
an_author = Author.objects.all()[0]
short_url = '/shortcut/%s/%s/' % (42424242, an_author.pk)
response = self.client.get(short_url)
self.assertEqual(response.status_code, 404)

View File

@ -0,0 +1,7 @@
from __future__ import absolute_import, unicode_literals
from django.conf.urls import patterns
urlpatterns = patterns('',
(r'^shortcut/(\d+)/(.*)/$', 'django.contrib.contenttypes.views.shortcut'),
)

View File

@ -13,43 +13,6 @@ class DefaultsTests(TestCase):
non_existing_urls = ['/views/non_existing_url/', # this is in urls.py non_existing_urls = ['/views/non_existing_url/', # this is in urls.py
'/views/other_non_existing_url/'] # this NOT in urls.py '/views/other_non_existing_url/'] # this NOT in urls.py
def test_shortcut_with_absolute_url(self):
"Can view a shortcut for an Author object that has a get_absolute_url method"
for obj in Author.objects.all():
short_url = '/views/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Author).id, obj.pk)
response = self.client.get(short_url)
self.assertRedirects(response, 'http://testserver%s' % obj.get_absolute_url(),
status_code=302, target_status_code=404)
def test_shortcut_no_absolute_url(self):
"Shortcuts for an object that has no get_absolute_url method raises 404"
for obj in Article.objects.all():
short_url = '/views/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Article).id, obj.pk)
response = self.client.get(short_url)
self.assertEqual(response.status_code, 404)
def test_wrong_type_pk(self):
short_url = '/views/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Author).id, 'nobody/expects')
response = self.client.get(short_url)
self.assertEqual(response.status_code, 404)
def test_shortcut_bad_pk(self):
short_url = '/views/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Author).id, '42424242')
response = self.client.get(short_url)
self.assertEqual(response.status_code, 404)
def test_nonint_content_type(self):
an_author = Author.objects.all()[0]
short_url = '/views/shortcut/%s/%s/' % ('spam', an_author.pk)
response = self.client.get(short_url)
self.assertEqual(response.status_code, 404)
def test_bad_content_type(self):
an_author = Author.objects.all()[0]
short_url = '/views/shortcut/%s/%s/' % (42424242, an_author.pk)
response = self.client.get(short_url)
self.assertEqual(response.status_code, 404)
def test_page_not_found(self): def test_page_not_found(self):
"A 404 status is returned by the page_not_found view" "A 404 status is returned by the page_not_found view"
for url in self.non_existing_urls: for url in self.non_existing_urls:

View File

@ -42,7 +42,6 @@ urlpatterns = patterns('',
(r'^$', views.index_page), (r'^$', views.index_page),
# Default views # Default views
(r'^shortcut/(\d+)/(.*)/$', 'django.views.defaults.shortcut'),
(r'^non_existing_url/', 'django.views.defaults.page_not_found'), (r'^non_existing_url/', 'django.views.defaults.page_not_found'),
(r'^server_error/', 'django.views.defaults.server_error'), (r'^server_error/', 'django.views.defaults.server_error'),