App Engine Python SDK version 1.7.4 (2)
[gae.git] / python / lib / django_1_4 / django / contrib / contenttypes / views.py
blob8d8e1c7a3e3841883554845e578a309654cfbb09
1 from django import http
2 from django.contrib.contenttypes.models import ContentType
3 from django.contrib.sites.models import Site, get_current_site
4 from django.core.exceptions import ObjectDoesNotExist
5 from django.utils.translation import ugettext as _
7 def shortcut(request, content_type_id, object_id):
8 """
9 Redirect to an object's page based on a content-type ID and an object ID.
10 """
11 # Look up the object, making sure it's got a get_absolute_url() function.
12 try:
13 content_type = ContentType.objects.get(pk=content_type_id)
14 if not content_type.model_class():
15 raise http.Http404(_(u"Content type %(ct_id)s object has no associated model") %
16 {'ct_id': content_type_id})
17 obj = content_type.get_object_for_this_type(pk=object_id)
18 except (ObjectDoesNotExist, ValueError):
19 raise http.Http404(_(u"Content type %(ct_id)s object %(obj_id)s doesn't exist") %
20 {'ct_id': content_type_id, 'obj_id': object_id})
22 try:
23 get_absolute_url = obj.get_absolute_url
24 except AttributeError:
25 raise http.Http404(_("%(ct_name)s objects don't have a get_absolute_url() method") %
26 {'ct_name': content_type.name})
27 absurl = get_absolute_url()
29 # Try to figure out the object's domain, so we can do a cross-site redirect
30 # if necessary.
32 # If the object actually defines a domain, we're done.
33 if absurl.startswith('http://') or absurl.startswith('https://'):
34 return http.HttpResponseRedirect(absurl)
36 # Otherwise, we need to introspect the object's relationships for a
37 # relation to the Site object
38 object_domain = None
40 if Site._meta.installed:
41 opts = obj._meta
43 # First, look for an many-to-many relationship to Site.
44 for field in opts.many_to_many:
45 if field.rel.to is Site:
46 try:
47 # Caveat: In the case of multiple related Sites, this just
48 # selects the *first* one, which is arbitrary.
49 object_domain = getattr(obj, field.name).all()[0].domain
50 except IndexError:
51 pass
52 if object_domain is not None:
53 break
55 # Next, look for a many-to-one relationship to Site.
56 if object_domain is None:
57 for field in obj._meta.fields:
58 if field.rel and field.rel.to is Site:
59 try:
60 object_domain = getattr(obj, field.name).domain
61 except Site.DoesNotExist:
62 pass
63 if object_domain is not None:
64 break
66 # Fall back to the current site (if possible).
67 if object_domain is None:
68 try:
69 object_domain = get_current_site(request).domain
70 except Site.DoesNotExist:
71 pass
73 # If all that malarkey found an object domain, use it. Otherwise, fall back
74 # to whatever get_absolute_url() returned.
75 if object_domain is not None:
76 protocol = request.is_secure() and 'https' or 'http'
77 return http.HttpResponseRedirect('%s://%s%s'
78 % (protocol, object_domain, absurl))
79 else:
80 return http.HttpResponseRedirect(absurl)