Source code for duck.backend.django.urls
"""
Proxy module for Django which is essential for configuring urlpatterns registered with Duck to be accessible within Django.
"""
import re
from typing import List
from django.urls import path, re_path
from django.views.decorators.http import require_http_methods
from duck.backend.django import views
from duck.backend.django.utils import duck_url_to_django_syntax
from duck.settings import SETTINGS
from duck.settings.loaded import SettingsLoaded
from duck.exceptions.all import (
PortError,
RouteError,
BlueprintError,
)
[docs]
class DjangoURLConflict(RouteError):
"""
Raised when a URL pattern that is said to be only known to Django has been
defined within Duck.
"""
[docs]
def get_duck_urlpatterns() -> List:
"""
Returns all urlpatterns registered within Duck including blueprint urlpatterns.
"""
duck_urlpatterns = SettingsLoaded.URLPATTERNS
for blueprint in SettingsLoaded.BLUEPRINTS:
duck_urlpatterns.extend(blueprint.urlpatterns)
return duck_urlpatterns
[docs]
def get_correct_urlpatterns() -> List:
"""
Returns all urlpatterns registered within Duck
converted to urlpatterns understood by Django.
"""
urlpatterns = []
duck_urlpatterns = get_duck_urlpatterns()
# Make new django urlpatterns
for urlpattern in duck_urlpatterns:
url, name, methods = (
urlpattern.get("url"),
urlpattern.get("name", None),
urlpattern.get("methods", []),
)
# Check if url is not matching DJANGO_SIDE_URLS
# DJANGO_SIDE_URLS are only known to Django not Duck.
django_side_urls = SETTINGS["DJANGO_SIDE_URLS"]
regex_url = re.compile(url)
if any([regex_url.fullmatch(i) for i in django_side_urls]):
raise DjangoURLConflict(
f"You seem to have defined that urlpattern '{urlpattern}' is only known to Django "
f"according to DJANGO_SIDE_URLS setting, yet you added it to Duck urlpatterns."
)
# Strip left forward slash if present to suppress Django warnings
url = url.lstrip("/")
duck_django_view = views.duck_django_view
if methods:
duck_django_view = require_http_methods(methods)(views.duck_django_view)
# add to django urlpatterns
if urlpattern.regex:
# This pattern is a regex url pattern
urlpatterns.append(
re_path(
"^" + url if not url.startswith('^') else url,
duck_django_view,
name=name,
))
else:
# its a normal url pattern
url = duck_url_to_django_syntax(url)
urlpatterns.append(
path(
url,
duck_django_view,
name=name,
))
return urlpatterns
urlpatterns = get_correct_urlpatterns()