Moved the bulk of the shortcut() function in django/views/defaults.py to a new module, django/contrib/contenttypes/views.py. As a result, django/views/defaults.py no longer relies on django.contrib.contenttypes. Of course, the shortcut() function is still available in the former module, for backwards compatibility. See the new FutureBackwardsIncompatibleChanges wiki page.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@9001 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2008-09-10 05:56:34 +00:00
parent 5cc93500e8
commit 40cb11a554
3 changed files with 81 additions and 68 deletions

View File

@ -148,9 +148,9 @@ class AdminSite(object):
return self.password_change_done(request) return self.password_change_done(request)
elif url == 'jsi18n': elif url == 'jsi18n':
return self.i18n_javascript(request) return self.i18n_javascript(request)
# urls starting with 'r/' are for the "show in web" links # URLs starting with 'r/' are for the "View on site" links.
elif url.startswith('r/'): elif url.startswith('r/'):
from django.views.defaults import shortcut from django.contrib.contenttypes.views import shortcut
return shortcut(request, *url.split('/')[1:]) return shortcut(request, *url.split('/')[1:])
else: else:
if '/' in url: if '/' in url:

View File

@ -0,0 +1,67 @@
from django import http
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site
from django.core.exceptions import ObjectDoesNotExist
def shortcut(request, content_type_id, object_id):
"Redirect to an object's page based on a content-type ID and an object ID."
# Look up the object, making sure it's got a get_absolute_url() function.
try:
content_type = ContentType.objects.get(pk=content_type_id)
obj = content_type.get_object_for_this_type(pk=object_id)
except ObjectDoesNotExist:
raise http.Http404("Content type %s object %s doesn't exist" % (content_type_id, object_id))
try:
absurl = obj.get_absolute_url()
except AttributeError:
raise http.Http404("%s objects don't have get_absolute_url() methods" % content_type.name)
# Try to figure out the object's domain, so we can do a cross-site redirect
# if necessary.
# If the object actually defines a domain, we're done.
if absurl.startswith('http://') or absurl.startswith('https://'):
return http.HttpResponseRedirect(absurl)
# Otherwise, we need to introspect the object's relationships for a
# relation to the Site object
object_domain = None
opts = obj._meta
# First, look for an many-to-many relationship to Site.
for field in opts.many_to_many:
if field.rel.to is Site:
try:
# Caveat: In the case of multiple related Sites, this just
# selects the *first* one, which is arbitrary.
object_domain = getattr(obj, field.name).all()[0].domain
except IndexError:
pass
if object_domain is not None:
break
# Next, look for a many-to-one relationship to Site.
if object_domain is None:
for field in obj._meta.fields:
if field.rel and field.rel.to is Site:
try:
object_domain = getattr(obj, field.name).domain
except Site.DoesNotExist:
pass
if object_domain is not None:
break
# Fall back to the current site (if possible).
if object_domain is None:
try:
object_domain = Site.objects.get_current().domain
except Site.DoesNotExist:
pass
# If all that malarkey found an object domain, use it. Otherwise, fall back
# to whatever get_absolute_url() returned.
if object_domain is not None:
protocol = request.is_secure() and 'https' or 'http'
return http.HttpResponseRedirect('%s://%s%s' % (protocol, object_domain, absurl))
else:
return http.HttpResponseRedirect(absurl)

View File

@ -1,70 +1,5 @@
from django.core.exceptions import ObjectDoesNotExist
from django.template import Context, RequestContext, loader
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site
from django import http from django import http
from django.template import Context, RequestContext, loader
def shortcut(request, content_type_id, object_id):
"Redirect to an object's page based on a content-type ID and an object ID."
# Look up the object, making sure it's got a get_absolute_url() function.
try:
content_type = ContentType.objects.get(pk=content_type_id)
obj = content_type.get_object_for_this_type(pk=object_id)
except ObjectDoesNotExist:
raise http.Http404, "Content type %s object %s doesn't exist" % (content_type_id, object_id)
try:
absurl = obj.get_absolute_url()
except AttributeError:
raise http.Http404, "%s objects don't have get_absolute_url() methods" % content_type.name
# Try to figure out the object's domain, so we can do a cross-site redirect
# if necessary.
# If the object actually defines a domain, we're done.
if absurl.startswith('http://') or absurl.startswith('https://'):
return http.HttpResponseRedirect(absurl)
object_domain = None
# Otherwise, we need to introspect the object's relationships for a
# relation to the Site object
opts = obj._meta
# First, look for an many-to-many relationship to sites
for field in opts.many_to_many:
if field.rel.to is Site:
try:
object_domain = getattr(obj, field.name).all()[0].domain
except IndexError:
pass
if object_domain is not None:
break
# Next look for a many-to-one relationship to site
if object_domain is None:
for field in obj._meta.fields:
if field.rel and field.rel.to is Site:
try:
object_domain = getattr(obj, field.name).domain
except Site.DoesNotExist:
pass
if object_domain is not None:
break
# Fall back to the current site (if possible)
if object_domain is None:
try:
object_domain = Site.objects.get_current().domain
except Site.DoesNotExist:
pass
# If all that malarkey found an object domain, use it; otherwise fall back
# to whatever get_absolute_url() returned.
if object_domain is not None:
protocol = request.is_secure() and 'https' or 'http'
return http.HttpResponseRedirect('%s://%s%s' % (protocol, object_domain, absurl))
else:
return http.HttpResponseRedirect(absurl)
def page_not_found(request, template_name='404.html'): def page_not_found(request, template_name='404.html'):
""" """
@ -87,3 +22,14 @@ def server_error(request, template_name='500.html'):
""" """
t = loader.get_template(template_name) # You need to create a 500.html template. t = loader.get_template(template_name) # You need to create a 500.html template.
return http.HttpResponseServerError(t.render(Context({}))) return http.HttpResponseServerError(t.render(Context({})))
def shortcut(request, content_type_id, object_id):
# TODO: Remove this in Django 2.0.
# This is a legacy view that depends on the contenttypes framework.
# The core logic was moved to django.contrib.contenttypes.views after
# Django 1.0, but this remains here for backwards compatibility.
# 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
return real_shortcut(request, content_type_id, object_id)