Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

views.py 3.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. from django.apps import apps
  2. from django.contrib.contenttypes.models import ContentType
  3. from django.contrib.sites.requests import RequestSite
  4. from django.core.exceptions import ObjectDoesNotExist
  5. from django.http import Http404, HttpResponseRedirect
  6. from django.utils.translation import gettext 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 Http404(
  16. _("Content type %(ct_id)s object has no associated model") %
  17. {'ct_id': content_type_id}
  18. )
  19. obj = content_type.get_object_for_this_type(pk=object_id)
  20. except (ObjectDoesNotExist, ValueError):
  21. raise Http404(
  22. _("Content type %(ct_id)s object %(obj_id)s doesn't exist") %
  23. {'ct_id': content_type_id, 'obj_id': object_id}
  24. )
  25. try:
  26. get_absolute_url = obj.get_absolute_url
  27. except AttributeError:
  28. raise Http404(
  29. _("%(ct_name)s objects don't have a get_absolute_url() method") %
  30. {'ct_name': content_type.name}
  31. )
  32. absurl = get_absolute_url()
  33. # Try to figure out the object's domain, so we can do a cross-site redirect
  34. # if necessary.
  35. # If the object actually defines a domain, we're done.
  36. if absurl.startswith(('http://', 'https://', '//')):
  37. return HttpResponseRedirect(absurl)
  38. # Otherwise, we need to introspect the object's relationships for a
  39. # relation to the Site object
  40. object_domain = None
  41. if apps.is_installed('django.contrib.sites'):
  42. Site = apps.get_model('sites.Site')
  43. opts = obj._meta
  44. # First, look for a many-to-many relationship to Site.
  45. for field in opts.many_to_many:
  46. if field.remote_field.model is Site:
  47. try:
  48. # Caveat: In the case of multiple related Sites, this just
  49. # selects the *first* one, which is arbitrary.
  50. object_domain = getattr(obj, field.name).all()[0].domain
  51. except IndexError:
  52. pass
  53. if object_domain is not None:
  54. 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.remote_field and field.remote_field.model is Site:
  59. try:
  60. site = getattr(obj, field.name)
  61. except Site.DoesNotExist:
  62. continue
  63. if site is not None:
  64. object_domain = site.domain
  65. if object_domain is not None:
  66. break
  67. # Fall back to the current site (if possible).
  68. if object_domain is None:
  69. try:
  70. object_domain = Site.objects.get_current(request).domain
  71. except Site.DoesNotExist:
  72. pass
  73. else:
  74. # Fall back to the current request's site.
  75. object_domain = RequestSite(request).domain
  76. # If all that malarkey found an object domain, use it. Otherwise, fall back
  77. # to whatever get_absolute_url() returned.
  78. if object_domain is not None:
  79. protocol = request.scheme
  80. return HttpResponseRedirect('%s://%s%s' % (protocol, object_domain, absurl))
  81. else:
  82. return HttpResponseRedirect(absurl)