Source code for mezzanine.utils.urls

from __future__ import unicode_literals
from future.builtins import str

import re
import unicodedata

from django.core.exceptions import ObjectDoesNotExist
from django.urls import resolve, reverse, NoReverseMatch, get_script_prefix
from django.shortcuts import redirect
from django.utils.encoding import smart_text

from django.utils.http import is_safe_url
from django.utils import translation

from mezzanine.conf import settings
from mezzanine.utils.importing import import_dotted_path


[docs]def admin_url(model, url, object_id=None): """ Returns the URL for the given model and admin url name. """ opts = model._meta url = "admin:%s_%s_%s" % (opts.app_label, opts.object_name.lower(), url) args = () if object_id is not None: args = (object_id,) return reverse(url, args=args)
[docs]def home_slug(): """ Returns the slug arg defined for the ``home`` urlpattern, which is the definitive source of the ``url`` field defined for an editable homepage object. """ prefix = get_script_prefix() slug = reverse("home") if slug.startswith(prefix): slug = '/' + slug[len(prefix):] try: return resolve(slug).kwargs["slug"] except KeyError: return slug
[docs]def slugify(s): """ Loads the callable defined by the ``SLUGIFY`` setting, which defaults to the ``slugify_unicode`` function. """ return import_dotted_path(settings.SLUGIFY)(s)
[docs]def slugify_unicode(s): """ Replacement for Django's slugify which allows unicode chars in slugs, for URLs in Chinese, Russian, etc. Adopted from https://github.com/mozilla/unicode-slugify/ """ chars = [] for char in str(smart_text(s)): cat = unicodedata.category(char)[0] if cat in "LN" or char in "-_~": chars.append(char) elif cat == "Z": chars.append(" ") return re.sub("[-\s]+", "-", "".join(chars).strip()).lower()
[docs]def unique_slug(queryset, slug_field, slug): """ Ensures a slug is unique for the given queryset, appending an integer to its end until the slug is unique. """ i = 0 while True: if i > 0: if i > 1: slug = slug.rsplit("-", 1)[0] slug = "%s-%s" % (slug, i) try: queryset.get(**{slug_field: slug}) except ObjectDoesNotExist: break i += 1 return slug
[docs]def next_url(request): """ Returns URL to redirect to from the ``next`` param in the request. """ next = request.GET.get("next", request.POST.get("next", "")) host = request.get_host() return next if next and is_safe_url(next, host=host) else None
[docs]def login_redirect(request): """ Returns the redirect response for login/signup. Favors: - next param - LOGIN_REDIRECT_URL setting - homepage """ ignorable_nexts = ("",) if "mezzanine.accounts" in settings.INSTALLED_APPS: from mezzanine.accounts import urls ignorable_nexts += (urls.SIGNUP_URL, urls.LOGIN_URL, urls.LOGOUT_URL) next = next_url(request) or "" if next in ignorable_nexts: next = settings.LOGIN_REDIRECT_URL if next == "/accounts/profile/": # Use the homepage if LOGIN_REDIRECT_URL is Django's defaut. next = get_script_prefix() else: try: next = reverse(next) except NoReverseMatch: pass return redirect(next)
[docs]def path_to_slug(path): """ Removes everything from the given URL path, including language code and ``PAGES_SLUG`` if any is set, returning a slug that would match a ``Page`` instance's slug. """ from mezzanine.urls import PAGES_SLUG lang_code = translation.get_language_from_path(path) for prefix in (lang_code, settings.SITE_PREFIX, PAGES_SLUG): if prefix: path = path.replace(prefix, "", 1) return clean_slashes(path) or "/"
[docs]def clean_slashes(path): """ Canonicalize path by removing leading slashes and conditionally removing trailing slashes. """ return path.strip("/") if settings.APPEND_SLASH else path.lstrip("/")