URLs reference#
Module summary#
next.urls exposes the router backends RouterBackend and FileRouterBackend.
It re-exports PageRoot from Utils reference, the labelled page tree a backend reports from page_roots for the system checks to walk and for the development watcher to observe.
It also exposes the RouterFactory and RouterManager that build and own them.
The URLPatternParser for bracket-segment parsing is part of the public surface.
It also exposes the page_reverse, page_reverse_lazy, and with_query reverse helpers, the get_multi_values query reader, and the Django integration name app_name.
The TrieURLResolver that dispatches URL resolution through a route trie completes the routing surface.
The parameter providers and the dependency markers DUrl (captured path segments) and DQuery (query string parameters) round out the public surface.
Public API#
Backends#
Every page view the file router generates carries a next_page_path attribute naming the page source, including the synthesised page.py location of a virtual template.djx route.
The form dispatcher reads it when it resolves a posted origin URL back to the page that re-renders after a validation failure.
Pluggable router backend contract, file router, and backend factory.
- class next.urls.backends.FileRouterBackend(pages_dir: str | None = None, *, app_dirs: bool | None = None, extra_root_paths: list[Path] | None = None, skip_dir_names: frozenset[str] | None = None, components_folder_name: str | None = None, options: dict[str, Any] | None = None)[source]#
Discover page.py (and virtual pages) under app and optional root trees.
- __init__(pages_dir: str | None = None, *, app_dirs: bool | None = None, extra_root_paths: list[Path] | None = None, skip_dir_names: frozenset[str] | None = None, components_folder_name: str | None = None, options: dict[str, Any] | None = None) None[source]#
Configure pages dir, extra roots, skip-dir names, and narrowed OPTIONS.
- components_folder_name() str | None[source]#
Return the folder name the tree walk registers components from.
- skip_dir_names() frozenset[str][source]#
Return the directory names this router’s own tree walk refuses.
- __eq__(other: object) bool[source]#
Return True when the other backend has the same pages configuration.
- class next.urls.backends.RouterBackend[source]#
Pluggable source of URLPattern and URLResolver entries.
- abstractmethod generate_urls() list[URLPattern | URLResolver][source]#
Patterns contributed by this backend to the project URLconf.
- page_roots() list[PageRoot][source]#
Labelled page trees this backend routes, for system checks to walk.
A backend that routes from somewhere else reports none, which leaves it out of every page-tree check and out of the development watcher.
- class next.urls.backends.RouterFactory[source]#
Build RouterBackend instances from PAGE_BACKENDS-style dicts.
- classmethod register_backend(name: str, backend_class: type[RouterBackend]) None[source]#
Map a dotted backend path to a class for create_backend.
Validates at registration so a bad class fails loudly here instead of silently on the first create_backend during a router reload.
Manager#
urlpatterns is a list holding a single TrieURLResolver that wraps a lazy sequence of router and form-action patterns.
include() therefore mounts one resolver, and the pattern collection is deferred to the first URL resolution instead of running while the root URLconf imports.
Code that reads next.urls.urlpatterns directly observes that one-element list, not the individual page patterns.
The wrapped sequence caches the concatenated pattern list against a pair of version counters, one owned by RouterManager and one by the form-action manager.
router_manager.reload() bumps the router counter, and registering or clearing form actions through form_action_manager bumps the forms counter, so the next access rebuilds the list exactly when something changed.
The counters are read after the pattern build, because expanding page modules can register form actions mid-build, so the cache stays valid for the post-registration state.
A registration that bypasses the manager and writes into a backend directly is not tracked by the counters and does not appear in the cached list.
The backends themselves are cached by router_manager and are only rebuilt when router_manager.reload() runs or when PAGE_BACKENDS changes.
A page added on disk after that first collection needs router_manager.reload(), which rebuilds the backends and clears the Django resolver cache.
Within a backend both the per-application pattern lists and the patterns from the roots configured in DIRS are memoised after the first scan, and a settings reload recreates the backend with fresh caches.
Reverse-name population iterates the wrapped sequence with reversed(), which it answers through an explicit __reversed__ that builds the pattern list once per pass.
RouterManager owns the active backend list, and the router_manager singleton exposes reload() to rebuild it.
reload() logs and skips a backend entry whose construction raises ValueError, TypeError, KeyError, or ImportError.
Any other exception from a custom backend propagates and stops startup.
backends reads the loaded list as a tuple without loading anything, which is how the system checks walk the routers they were handed.
version is the cache token the lazy urlpatterns concat keys on, bumped by every reload(), and a caller that derives its own cache from the router set reads it for the same purpose.
Router manager, lazy urlpatterns sequence, and settings-reload wiring.
RouterManager owns the list of active RouterBackend instances and rebuilds it from NEXT_FRAMEWORK[“PAGE_BACKENDS”] whenever framework settings change. _LazyUrlPatterns is the sequence wrapped by the module-level resolver built from NEXT_FRAMEWORK[“URL_RESOLVER”] so the first resolve triggers router and form-action resolution without walking the page tree at import time.
- class next.urls.manager.RouterManager[source]#
Load RouterBackend instances from NEXT_FRAMEWORK and iterate them.
- version: int = 0#
Cache token for the lazy urlpatterns concat, bumped by reload().
Read it to key a cache of your own on the active backend list. It is a plain attribute rather than a property because the lazy urlpatterns concat reads it on every resolve.
- property backends: tuple[RouterBackend, ...]#
Return the loaded backends in routing order.
Reading them loads nothing. Iterating the manager builds the list on first use and reload() rebuilds it, so a caller that needs the configured set asks after one of those.
- __iter__() Generator[URLPattern | URLResolver, None, None][source]#
All patterns from each backend, loading config on first use.
- __getitem__(index: int) RouterBackend[source]#
Return the backend at the given index.
- reload() None[source]#
Rebuild backends from PAGE_BACKENDS and notify listeners.
The Django URL resolver caches resolved patterns. The cache is cleared here so the next request sees the freshly built backend list. The router_reloaded signal fires after the rebuild and the cache flush so receivers observe a consistent state.
Resolver#
TrieURLResolver subclasses URLResolver and narrows each resolve() call to a handful of candidate patterns.
A route without parameters hits a dictionary keyed by the full route string, and a parameterised route is collected by a walk over a trie of path segments.
The candidates are then tried with the standard pattern.resolve() in their original list order, so overlapping routes keep Django’s first-match-wins semantics and converters behave as in plain Django.
A miss falls back to the inherited linear scan, which raises the canonical Resolver404 with a complete tried list and also covers patterns the trie cannot index, such as ones built with re_path().
On a successful match ResolverMatch.tried lists only the candidates that were actually tried, not every pattern preceding the winner.
The internal route index is versioned by the same counters as the pattern concat, so a router reload or a late form-action registration rebuilds it before the next resolution.
The URL_RESOLVER setting names the resolver class, so pointing it at django.urls.resolvers.URLResolver or a custom subclass replaces the trie dispatch.
See URL router for the algorithm walk-through.
Trie-backed URL resolver that narrows resolve() to a few candidates.
The file router owns its whole subtree, so the route list is a ready-made trie. Candidates for a path are picked in O(depth) from a static route map plus a segment trie, then tried in original pattern order, which keeps Django’s first-match-wins semantics for overlapping routes.
- class next.urls.resolver.TrieURLResolver(pattern, urlconf_name, default_kwargs=None, app_name=None, namespace=None)[source]#
URLResolver that dispatches resolve() through a route trie.
The index is rebuilt whenever the version_token() of the wrapped patterns changes. Any miss falls back to the inherited linear scan for the canonical Resolver404 with a complete tried list.
Parser#
Map bracket segments in file-based URL paths to Django converters.
The URLPatternParser turns a filesystem-style logical URL trail into a Django path pattern. Bracket syntax [name] maps to <str:name>, [int:id] maps to <int:id>, and [[args]] maps to <path:args>.
- exception next.urls.parser.DuplicateURLParameterError(param_name: str, url_path: str, file_path: Path | None = None)[source]#
Raised when bracket segments in one route conflict after normalisation.
Covers a repeated normalised parameter name (- maps to _) and a second [[wildcard]] segment, both of which Django would otherwise reject only at resolve time or resolve ambiguously.
- class next.urls.parser.URLPatternParser[source]#
Map bracket segments in a file-based path to Django path converters.
The url_path string is the logical URL trail built from directory names. An empty string means the tree root. It is not a pathlib.Path. The on-disk file is the second value from the page-tree scanner.
- duplicate_parameter_error#
alias of
DuplicateURLParameterError
- parse_url_pattern(url_path: str) tuple[str, dict[str, str]][source]#
Return the Django path string and parameter names for url_path.
Dispatcher#
Deep import path
The names in next.urls.dispatcher are not re-exported from next.urls.
Import them through the submodule path when a custom backend or test needs to call them directly.
Walk filesystem page trees once to emit routes and register components.
FilesystemTreeDispatcher runs the shared walk_page_tree once per page-tree root. It yields (url_path, page_file) pairs for every discovered page.py (plus virtual template.djx-only pages), and registers _components folders it encounters along the way.
- class next.urls.dispatcher.FilesystemTreeDispatcher(skip_dir_names: Iterable[str], *, components_folder_name: str, register_components: bool)[source]#
Run one depth-first walk that yields routes and skips component folders.
Reverse helpers#
- next.urls.reverse.page_reverse(path_template: str = '', *, namespace: str = 'next', **kwargs) str[source]#
Reverse a file-router page URL from its directory-tree template.
- next.urls.reverse.page_reverse_lazy(path_template='', *, namespace=app_name, **kwargs)#
Lazy variant of
page_reverse, the wayreverse_lazy()pairs withreverse(). The URL resolves when the value is first coerced tostr, which makes it safe in positions evaluated at class-definition time, before the URLconf is ready, such asMeta.success_urlon a form class.
Markers#
Dependency injection markers and providers for URL-derived parameters.
DUrl is an annotation marker used in @context and view-derived callables to pull a value from URL kwargs. DQuery is the parallel marker that reads request.GET query-string parameters. The provider classes plug into the next.deps resolver via RegisteredParameterProvider and expose HttpRequest, DUrl[…] values, raw URL kwargs by name, and DQuery[…] values.
- class next.urls.markers.DQuery[source]#
Annotation marker for a request.GET parameter.
Use DQuery[str], DQuery[int], DQuery[bool], or DQuery[float] for scalar values, or DQuery[list[T]] for multi-value parameters. The list form accepts the plain repeated form ?brand=a&brand=b, the qs-style bracket suffix ?brand[]=a&brand[]=b emitted by axios and other front-end clients, and the comma-delimited form ?brand=a,b produced by qs.stringify with the comma array format. The provider returns the parameter default when the key is absent, or None when no default is given.
- class next.urls.markers.DUrl[source]#
Annotation for a captured URL path parameter with optional type coercion.
Use DUrl[SomeType] to read the captured segment that matches the parameter name and coerce it. Use DUrl[“param”] to read a named segment without coercion. Use DUrl[“param”, SomeType] to read a named segment and coerce it, which is the form to reach for when the parameter name differs from the captured segment name.
- classmethod __class_getitem__(item: object) object[source]#
Build the marker for the type, named-key, and named-key-with-type forms.
A plain type follows the standard generic path. A string, or a (string, type) tuple, is wrapped so the provider can read the captured segment by an explicit name rather than the parameter name.
- class next.urls.markers.HttpRequestProvider[source]#
Supply HttpRequest from context.request.
The provider claims parameters annotated as HttpRequest or HttpRequest | None. The optional form lets handlers keep request: HttpRequest | None = None for direct unit-test calls without giving up dependency injection.
- priority = 50#
- can_handle(param: inspect.Parameter, context: ResolutionContext) bool[source]#
Return True when the parameter expects HttpRequest and a request exists.
- resolve(_param: inspect.Parameter, context: ResolutionContext) object[source]#
Return the request from the resolution context.
- class next.urls.markers.QueryParamProvider[source]#
Resolve DQuery[…] parameters from request.GET.
- priority = 80#
- can_handle(param: inspect.Parameter, context: ResolutionContext) bool[source]#
Return True for DQuery[…] annotations when a request is present.
- resolve(param: inspect.Parameter, context: ResolutionContext) object[source]#
Pull the value from request.GET and coerce it to the annotated type.
- class next.urls.markers.UrlByAnnotationProvider[source]#
Fill DUrl[…] parameters from url_kwargs.
- priority = 60#
- can_handle(param: inspect.Parameter, _context: ResolutionContext) bool[source]#
Return True when the parameter uses a DUrl annotation.
- resolve(param: inspect.Parameter, context: ResolutionContext) object[source]#
URL value for the parameter, coerced when the annotation names a type.
- class next.urls.markers.UrlKwargsProvider[source]#
Fill parameters by name from url_kwargs.
- priority = 70#
- can_handle(param: inspect.Parameter, context: ResolutionContext) bool[source]#
Return True when url_kwargs contains this parameter name.
- resolve(param: inspect.Parameter, context: ResolutionContext) object[source]#
Raw URL value for the parameter, coerced to the annotation when possible.
- next.urls.markers.get_multi_values(request: HttpRequest, name: str) list[str][source]#
Return all values for name from
request.GET.Tries three wire formats in order: plain repeated keys (
?brand=a&brand=b), bracket suffix (?brand[]=a&brand[]=b), and comma-delimited (?brand=a,b). Returns an empty list when the parameter is absent in all three forms.
Parameter providers#
The following provider classes are registered with the next.deps resolver at startup.
They are exported from next.urls for introspection and for authors writing custom providers that delegate to them.
Provider |
What it supplies |
|---|---|
|
Supplies the |
|
Supplies a URL kwarg value for parameters annotated with |
|
Supplies a URL kwarg value by parameter name, coercing the raw string to the parameter annotation when one is present.
|
|
Supplies |
See Dependency resolver for the full provider registration sequence and the resolution order.
DUrl and DQuery both accept str, int, bool, float, UUID, Decimal, date, and datetime.
DQuery additionally accepts list[T] for any of those scalars.
The following table is the canonical coercion reference. A value that fails to parse falls back to the raw captured string rather than raising.
Annotation type |
Accepted wire values |
Result |
|---|---|---|
|
Any captured string. |
Returned unchanged. |
|
Decimal digit string. |
|
|
Decimal float string. |
|
|
|
Boolean. |
|
Canonical UUID string, or an already parsed |
|
|
Numeric string parseable by |
|
|
ISO 8601 date accepted by |
|
|
ISO 8601 datetime accepted by |
|
See Dependency injection and File router for the narrative coverage of each marker.
Signals#
The URL subsystem fires two signals.
route_registered.Sent by
FileRouterBackendonce per registered route, including virtualtemplate.djxroutes, with theurl_pathandfile_pathkeyword arguments.router_reloaded.Sent by the router manager class after the router rebuilds, with no keyword arguments. The sender is the
RouterManagerclass.
See Signals reference and Signals for the wider signal catalog.
Checks#
next.urls.checks registers Django system checks that validate the URL configuration at startup.
check_next_pages_configuration.Validates the
NEXT_FRAMEWORK['PAGE_BACKENDS']structure, theBACKENDpath, and per-backendDIRS/APP_DIRS/PAGES_DIR/OPTIONSkeys.check_url_patterns.Collects patterns from every configured tree, application pages and root
DIRSalike. Fails with next.E015 when two file routes convert to exactly the same Django path string. Fails with next.E028 when a route repeats a captured parameter name, listing every conflicting name. Reports next.E016 when pattern collection from a router raises.check_reverse_name_collisions.Fails with next.E039 when two distinct routes collapse to the same reverse URL name. It reuses the same pattern collection but leaves collection errors to
check_url_patterns, so next.E016 surfaces only once.
System checks for the URL routing subsystem.
- next.urls.checks.check_next_pages_configuration(*args, **kwargs) list[CheckMessage][source]
Validate PAGE_BACKENDS inside merged NEXT_FRAMEWORK.
- next.urls.checks.check_reverse_name_collisions(*args, **kwargs) list[CheckMessage][source]
Fail when two distinct routes collapse to the same reverse URL name.
See also#
See also
File router for the topic guide. URL reversing for the reverse helpers. URL router for the dispatcher internals.