app/django/views/defaults.py
changeset 323 ff1a9aa48cfd
parent 54 03e267d67478
equal deleted inserted replaced
322:6641e941ef1e 323:ff1a9aa48cfd
     1 from django.core.exceptions import ObjectDoesNotExist
     1 from django import http
     2 from django.template import Context, RequestContext, loader
     2 from django.template import Context, RequestContext, loader
     3 from django.contrib.contenttypes.models import ContentType
       
     4 from django.contrib.sites.models import Site
       
     5 from django import http
       
     6 
       
     7 def shortcut(request, content_type_id, object_id):
       
     8     "Redirect to an object's page based on a content-type ID and an object ID."
       
     9     # Look up the object, making sure it's got a get_absolute_url() function.
       
    10     try:
       
    11         content_type = ContentType.objects.get(pk=content_type_id)
       
    12         obj = content_type.get_object_for_this_type(pk=object_id)
       
    13     except ObjectDoesNotExist:
       
    14         raise http.Http404, "Content type %s object %s doesn't exist" % (content_type_id, object_id)
       
    15     try:
       
    16         absurl = obj.get_absolute_url()
       
    17     except AttributeError:
       
    18         raise http.Http404, "%s objects don't have get_absolute_url() methods" % content_type.name
       
    19 
       
    20     # Try to figure out the object's domain, so we can do a cross-site redirect
       
    21     # if necessary.
       
    22 
       
    23     # If the object actually defines a domain, we're done.
       
    24     if absurl.startswith('http://') or absurl.startswith('https://'):
       
    25         return http.HttpResponseRedirect(absurl)
       
    26 
       
    27     object_domain = None
       
    28 
       
    29     # Otherwise, we need to introspect the object's relationships for a
       
    30     # relation to the Site object
       
    31     opts = obj._meta
       
    32 
       
    33     # First, look for an many-to-many relationship to sites
       
    34     for field in opts.many_to_many:
       
    35         if field.rel.to is Site:
       
    36             try:
       
    37                 object_domain = getattr(obj, field.name).all()[0].domain
       
    38             except IndexError:
       
    39                 pass
       
    40             if object_domain is not None:
       
    41                 break
       
    42 
       
    43     # Next look for a many-to-one relationship to site
       
    44     if object_domain is None:
       
    45         for field in obj._meta.fields:
       
    46             if field.rel and field.rel.to is Site:
       
    47                 try:
       
    48                     object_domain = getattr(obj, field.name).domain
       
    49                 except Site.DoesNotExist:
       
    50                     pass
       
    51                 if object_domain is not None:
       
    52                     break
       
    53 
       
    54     # Fall back to the current site (if possible)
       
    55     if object_domain is None:
       
    56         try:
       
    57             object_domain = Site.objects.get_current().domain
       
    58         except Site.DoesNotExist:
       
    59             pass
       
    60 
       
    61     # If all that malarkey found an object domain, use it; otherwise fall back
       
    62     # to whatever get_absolute_url() returned.
       
    63     if object_domain is not None:
       
    64         protocol = request.is_secure() and 'https' or 'http'
       
    65         return http.HttpResponseRedirect('%s://%s%s' % (protocol, object_domain, absurl))
       
    66     else:
       
    67         return http.HttpResponseRedirect(absurl)
       
    68 
     3 
    69 def page_not_found(request, template_name='404.html'):
     4 def page_not_found(request, template_name='404.html'):
    70     """
     5     """
    71     Default 404 handler, which looks for the requested URL in the redirects
     6     Default 404 handler.
    72     table, redirects if found, and displays 404 page if not redirected.
       
    73 
     7 
    74     Templates: `404.html`
     8     Templates: `404.html`
    75     Context:
     9     Context:
    76         request_path
    10         request_path
    77             The path of the requested URL (e.g., '/app/pages/bad_page/')
    11             The path of the requested URL (e.g., '/app/pages/bad_page/')
    86     Templates: `500.html`
    20     Templates: `500.html`
    87     Context: None
    21     Context: None
    88     """
    22     """
    89     t = loader.get_template(template_name) # You need to create a 500.html template.
    23     t = loader.get_template(template_name) # You need to create a 500.html template.
    90     return http.HttpResponseServerError(t.render(Context({})))
    24     return http.HttpResponseServerError(t.render(Context({})))
       
    25 
       
    26 def shortcut(request, content_type_id, object_id):
       
    27     # TODO: Remove this in Django 2.0.
       
    28     # This is a legacy view that depends on the contenttypes framework.
       
    29     # The core logic was moved to django.contrib.contenttypes.views after
       
    30     # Django 1.0, but this remains here for backwards compatibility.
       
    31     # Note that the import is *within* this function, rather than being at
       
    32     # module level, because we don't want to assume people have contenttypes
       
    33     # installed.
       
    34     from django.contrib.contenttypes.views import shortcut as real_shortcut
       
    35     return real_shortcut(request, content_type_id, object_id)