Commit 40cb11a5 authored by Adrian Holovaty's avatar Adrian Holovaty
Browse files

Moved the bulk of the shortcut() function in django/views/defaults.py to a new...

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
parent 5cc93500
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -148,9 +148,9 @@ class AdminSite(object):
            return self.password_change_done(request)
        elif url == 'jsi18n':
            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/'):
            from django.views.defaults import shortcut
            from django.contrib.contenttypes.views import shortcut
            return shortcut(request, *url.split('/')[1:])
        else:
            if '/' in url:
+67 −0
Original line number Diff line number Diff line
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)
+12 −66
Original line number Diff line number Diff line
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

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)
from django.template import Context, RequestContext, loader

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.
    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)