/django/contrib/contenttypes/views.py
Python | 71 lines | 49 code | 9 blank | 13 comment | 22 complexity | deeda1cbd920ee0e6c95d200f7f1d31f MD5 | raw file
Possible License(s): BSD-3-Clause
1from django import http 2from django.contrib.contenttypes.models import ContentType 3from django.contrib.sites.models import Site, get_current_site 4from django.core.exceptions import ObjectDoesNotExist 5 6def 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 if not content_type.model_class(): 12 raise http.Http404("Content type %s object has no associated model" % content_type_id) 13 obj = content_type.get_object_for_this_type(pk=object_id) 14 except (ObjectDoesNotExist, ValueError): 15 raise http.Http404("Content type %s object %s doesn't exist" % (content_type_id, object_id)) 16 try: 17 absurl = obj.get_absolute_url() 18 except AttributeError: 19 raise http.Http404("%s objects don't have get_absolute_url() methods" % content_type.name) 20 21 # Try to figure out the object's domain, so we can do a cross-site redirect 22 # if necessary. 23 24 # If the object actually defines a domain, we're done. 25 if absurl.startswith('http://') or absurl.startswith('https://'): 26 return http.HttpResponseRedirect(absurl) 27 28 # Otherwise, we need to introspect the object's relationships for a 29 # relation to the Site object 30 object_domain = None 31 32 if Site._meta.installed: 33 opts = obj._meta 34 35 # First, look for an many-to-many relationship to Site. 36 for field in opts.many_to_many: 37 if field.rel.to is Site: 38 try: 39 # Caveat: In the case of multiple related Sites, this just 40 # selects the *first* one, which is arbitrary. 41 object_domain = getattr(obj, field.name).all()[0].domain 42 except IndexError: 43 pass 44 if object_domain is not None: 45 break 46 47 # Next, look for a many-to-one relationship to Site. 48 if object_domain is None: 49 for field in obj._meta.fields: 50 if field.rel and field.rel.to is Site: 51 try: 52 object_domain = getattr(obj, field.name).domain 53 except Site.DoesNotExist: 54 pass 55 if object_domain is not None: 56 break 57 58 # Fall back to the current site (if possible). 59 if object_domain is None: 60 try: 61 object_domain = get_current_site(request).domain 62 except Site.DoesNotExist: 63 pass 64 65 # If all that malarkey found an object domain, use it. Otherwise, fall back 66 # to whatever get_absolute_url() returned. 67 if object_domain is not None: 68 protocol = request.is_secure() and 'https' or 'http' 69 return http.HttpResponseRedirect('%s://%s%s' % (protocol, object_domain, absurl)) 70 else: 71 return http.HttpResponseRedirect(absurl)