mysteriendrama/lib/python3.11/site-packages/django/contrib/contenttypes/views.py
2023-07-22 12:13:39 +02:00

89 lines
3.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from django.apps import apps
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.shortcuts import get_current_site
from django.core.exceptions import ObjectDoesNotExist
from django.http import Http404, HttpResponseRedirect
from django.utils.translation import gettext as _
def shortcut(request, content_type_id, object_id):
"""
Redirect to an object's page based on a content-type ID and an object ID.
"""
# Look up the object, making sure it's got a get_absolute_url() function.
try:
content_type = ContentType.objects.get(pk=content_type_id)
if not content_type.model_class():
raise Http404(
_("Content type %(ct_id)s object has no associated model")
% {"ct_id": content_type_id}
)
obj = content_type.get_object_for_this_type(pk=object_id)
except (ObjectDoesNotExist, ValueError):
raise Http404(
_("Content type %(ct_id)s object %(obj_id)s doesnt exist")
% {"ct_id": content_type_id, "obj_id": object_id}
)
try:
get_absolute_url = obj.get_absolute_url
except AttributeError:
raise Http404(
_("%(ct_name)s objects dont have a get_absolute_url() method")
% {"ct_name": content_type.name}
)
absurl = get_absolute_url()
# Try to figure out the object's domain, so we can do a cross-site redirect
# if necessary.
# If the object actually defines a domain, we're done.
if absurl.startswith(("http://", "https://", "//")):
return HttpResponseRedirect(absurl)
# Otherwise, we need to introspect the object's relationships for a
# relation to the Site object
try:
object_domain = get_current_site(request).domain
except ObjectDoesNotExist:
object_domain = None
if apps.is_installed("django.contrib.sites"):
Site = apps.get_model("sites.Site")
opts = obj._meta
for field in opts.many_to_many:
# Look for a many-to-many relationship to Site.
if field.remote_field.model is Site:
site_qs = getattr(obj, field.name).all()
if object_domain and site_qs.filter(domain=object_domain).exists():
# The current site's domain matches a site attached to the
# object.
break
# Caveat: In the case of multiple related Sites, this just
# selects the *first* one, which is arbitrary.
site = site_qs.first()
if site:
object_domain = site.domain
break
else:
# No many-to-many relationship to Site found. Look for a
# many-to-one relationship to Site.
for field in obj._meta.fields:
if field.remote_field and field.remote_field.model is Site:
try:
site = getattr(obj, field.name)
except Site.DoesNotExist:
continue
if site is not None:
object_domain = site.domain
break
# If all that malarkey found an object domain, use it. Otherwise, fall back
# to whatever get_absolute_url() returned.
if object_domain is not None:
protocol = request.scheme
return HttpResponseRedirect("%s://%s%s" % (protocol, object_domain, absurl))
else:
return HttpResponseRedirect(absurl)