mirror of
https://github.com/django-components/django-components.git
synced 2025-11-13 12:21:53 +00:00
refactor: do not call URLResolver._populate() if not needed
This commit is contained in:
parent
39e4d78dc5
commit
77df93b5b1
6 changed files with 38 additions and 11 deletions
|
|
@ -1,5 +1,11 @@
|
|||
# Release notes
|
||||
|
||||
## v0.143.1
|
||||
|
||||
#### Fix
|
||||
|
||||
- Make django-component's position in Django's `INSTALLED_APPS` more lenient by not calling Django's `URLResolver._populate()` if `URLResolver` hasn't been resolved before ([See thread](https://discord.com/channels/1417824875023700000/1417825089675853906/1437034834118840411)).
|
||||
|
||||
## v0.143.0
|
||||
|
||||
#### Feat
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||
|
||||
[project]
|
||||
name = "django_components"
|
||||
version = "0.143.0"
|
||||
version = "0.143.1"
|
||||
requires-python = ">=3.8, <4.0"
|
||||
description = "A way to create simple reusable template components in Django."
|
||||
keywords = ["django", "components", "css", "js", "html"]
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@ asv==0.6.5
|
|||
# via -r requirements-dev.in
|
||||
asv-runner==0.2.1
|
||||
# via asv
|
||||
backports-asyncio-runner==1.2.0
|
||||
# via pytest-asyncio
|
||||
build==1.3.0
|
||||
# via asv
|
||||
cachetools==6.2.0
|
||||
|
|
|
|||
|
|
@ -1163,9 +1163,7 @@ class ExtensionManager:
|
|||
extensions_url_resolver.url_patterns = urls
|
||||
|
||||
# Rebuild URL resolver cache to be able to resolve the new routes by their names.
|
||||
urlconf = get_urlconf()
|
||||
resolver = get_resolver(urlconf)
|
||||
resolver._populate()
|
||||
self._lazy_populate_resolver()
|
||||
|
||||
# Flush stored events
|
||||
#
|
||||
|
|
@ -1190,6 +1188,22 @@ class ExtensionManager:
|
|||
getattr(self, hook)(data)
|
||||
self._events = []
|
||||
|
||||
# Django processes the paths from `urlpatterns` only once.
|
||||
# This is at conflict with how we handle URL paths introduced by extensions,
|
||||
# which may happen AFTER Django processes `urlpatterns`.
|
||||
# If that happens, we need to force Django to re-process `urlpatterns`.
|
||||
# If we don't do it, then the new paths added by our extensions won't work
|
||||
# with e.g. `django.url.reverse()`.
|
||||
# See https://discord.com/channels/1417824875023700000/1417825089675853906/1437034834118840411
|
||||
def _lazy_populate_resolver(self) -> None:
|
||||
urlconf = get_urlconf()
|
||||
root_resolver = get_resolver(urlconf)
|
||||
# However, if Django has NOT yet processed the `urlpatterns`, then do nothing.
|
||||
# If we called `_populate()` in such case, we may break people's projects
|
||||
# as the values may be resolved prematurely, before all the needed code is loaded.
|
||||
if root_resolver._populated:
|
||||
root_resolver._populate()
|
||||
|
||||
def get_extension(self, name: str) -> ComponentExtension:
|
||||
for extension in self.extensions:
|
||||
if extension.name == name:
|
||||
|
|
@ -1221,12 +1235,8 @@ class ExtensionManager:
|
|||
all_urls.append(urlpattern)
|
||||
did_add_urls = True
|
||||
|
||||
# Force Django's URLResolver to update its lookups, so things like `reverse()` work
|
||||
if did_add_urls:
|
||||
# Django's root URLResolver
|
||||
urlconf = get_urlconf()
|
||||
root_resolver = get_resolver(urlconf)
|
||||
root_resolver._populate()
|
||||
self._lazy_populate_resolver()
|
||||
|
||||
def remove_extension_urls(self, name: str, urls: List[URLRoute]) -> None:
|
||||
if not self._initialized:
|
||||
|
|
|
|||
|
|
@ -585,5 +585,11 @@ def _clear_djc_global_state(
|
|||
if gc_collect:
|
||||
gc.collect()
|
||||
|
||||
# Clear Django's URL resolver cache, so that any URLs that were added
|
||||
# during tests are removed.
|
||||
from django.urls.resolvers import _get_cached_resolver # noqa: PLC0415
|
||||
|
||||
_get_cached_resolver.cache_clear()
|
||||
|
||||
global IS_TESTING # noqa: PLW0603
|
||||
IS_TESTING = False
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import pytest
|
|||
from django.http import HttpRequest, HttpResponse
|
||||
from django.template import Context, Origin, Template
|
||||
from django.test import Client
|
||||
from django.urls import get_resolver, get_urlconf
|
||||
|
||||
from django_components import Component, Slot, SlotNode, register, registry
|
||||
from django_components.app_settings import app_settings
|
||||
|
|
@ -649,6 +650,12 @@ class TestExtensionHooks:
|
|||
|
||||
@djc_test
|
||||
class TestExtensionViews:
|
||||
@djc_test(components_settings={"extensions": [DummyExtension]})
|
||||
def test_resolver_not_populated_needlessly(self):
|
||||
urlconf = get_urlconf()
|
||||
resolver = get_resolver(urlconf)
|
||||
assert not resolver._populated
|
||||
|
||||
@djc_test(components_settings={"extensions": [DummyExtension]})
|
||||
def test_views(self):
|
||||
client = Client()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue