Django

Code

root/django/trunk/django/contrib/contenttypes/views.py

Revision 9001, 2.7 kB (checked in by adrian, 2 months ago)

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.

Line 
1 from django import http
2 from django.contrib.contenttypes.models import ContentType
3 from django.contrib.sites.models import Site
4 from django.core.exceptions import ObjectDoesNotExist
5
6 def shortcut(request, content_type_id, object_id):
7     "Redirect to an object's page based on a content-type ID and an object ID."
8     # Look up the object, making sure it's got a get_absolute_url() function.
9     try:
10         content_type = ContentType.objects.get(pk=content_type_id)
11         obj = content_type.get_object_for_this_type(pk=object_id)
12     except ObjectDoesNotExist:
13         raise http.Http404("Content type %s object %s doesn't exist" % (content_type_id, object_id))
14     try:
15         absurl = obj.get_absolute_url()
16     except AttributeError:
17         raise http.Http404("%s objects don't have get_absolute_url() methods" % content_type.name)
18
19     # Try to figure out the object's domain, so we can do a cross-site redirect
20     # if necessary.
21
22     # If the object actually defines a domain, we're done.
23     if absurl.startswith('http://') or absurl.startswith('https://'):
24         return http.HttpResponseRedirect(absurl)
25
26     # Otherwise, we need to introspect the object's relationships for a
27     # relation to the Site object
28     object_domain = None
29     opts = obj._meta
30
31     # First, look for an many-to-many relationship to Site.
32     for field in opts.many_to_many:
33         if field.rel.to is Site:
34             try:
35                 # Caveat: In the case of multiple related Sites, this just
36                 # selects the *first* one, which is arbitrary.
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)
Note: See TracBrowser for help on using the browser.