Skip to content

Commit cc265e8

Browse files
committed
Rework i18n pattern handling and bump version
1 parent fdf177a commit cc265e8

File tree

2 files changed

+37
-39
lines changed

2 files changed

+37
-39
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "django-tomselect"
7-
version = "2025.7.1"
7+
version = "2025.9.1"
88
description = "Django autocomplete widgets and views using Tom Select"
99
authors = [{ name = "Jack Linke", email = "[email protected]" }]
1010
license = "MIT"

src/django_tomselect/utils.py

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55

66
from django.conf import settings
77
from django.urls import NoReverseMatch, reverse
8-
from django.urls.base import reverse_lazy
8+
from django.utils import translation
99
from django.utils.html import escape
10-
from django.utils.translation import get_language
1110

1211
from django_tomselect.logging import package_logger
1312

@@ -22,48 +21,47 @@
2221

2322
def safe_reverse(viewname: str, args: list | None = None, kwargs: dict | None = None) -> str:
2423
"""Safely reverse url, handling i18n edge cases when USE_I18N is True but i18n URL patterns aren't included."""
24+
# Store the current language
25+
current_language = translation.get_language()
26+
2527
try:
26-
# First try normal reversal
27-
return reverse(viewname, args=args, kwargs=kwargs)
28-
except NoReverseMatch as e:
29-
# Check if this might be an i18n-related issue
30-
if settings.USE_I18N and get_language():
31-
# Try to extract the actual error message
32-
error_msg = str(e)
33-
language_code = get_language()
34-
35-
# Check if the error is about a language namespace
36-
if f"'{language_code}' is not a registered namespace" in error_msg:
37-
package_logger.debug(
38-
"URL reversal failed due to missing i18n namespace '%s'. "
39-
"This usually means django.conf.urls.i18n is not included in urlpatterns. "
40-
"Attempting fallback URL reversal.",
41-
language_code,
42-
)
43-
44-
# Try to reverse without language prefix by temporarily deactivating translations
45-
from django.utils import translation
46-
47-
current_language = translation.get_language()
48-
try:
49-
# Deactivate translations temporarily
28+
# If i18n is enabled but there's a problem with url reversal, temporarily deactivate
29+
# translations to avoid issues with missing i18n URL patterns.
30+
if settings.USE_I18N and current_language:
31+
# First, try with language activated
32+
try:
33+
return reverse(viewname, args=args, kwargs=kwargs)
34+
except NoReverseMatch as e:
35+
error_msg = str(e)
36+
# Check if the error is about a language namespace
37+
if f"'{current_language}' is not a registered namespace" in error_msg:
38+
package_logger.debug(
39+
"URL reversal failed due to missing i18n namespace '%s'. "
40+
"This usually means django.conf.urls.i18n is not included in urlpatterns. "
41+
"Attempting fallback URL reversal without language activation.",
42+
current_language,
43+
)
44+
# Deactivate translations and try again
5045
translation.deactivate()
51-
return reverse(viewname, args=args, kwargs=kwargs)
52-
except NoReverseMatch:
53-
# If it still fails, re-raise the original error
54-
raise e
55-
finally:
56-
# Restore the original language
57-
if current_language:
58-
translation.activate(current_language)
59-
60-
# If not i18n related or fallback didn't work, re-raise
46+
try:
47+
return reverse(viewname, args=args, kwargs=kwargs)
48+
finally:
49+
# Always restore the original language
50+
if current_language:
51+
translation.activate(current_language)
52+
else:
53+
# Different error, re-raise
54+
raise
55+
else:
56+
# No i18n or no language activated, use regular reversal
57+
return reverse(viewname, args=args, kwargs=kwargs)
58+
except Exception as e:
59+
package_logger.error("Failed to reverse URL %s: %s", viewname, e)
6160
raise
6261

6362

6463
def safe_reverse_lazy(viewname: str, args: list | None = None, kwargs: dict | None = None):
65-
"""
66-
Lazy version of safe_reverse that handles i18n edge cases.
64+
"""Lazy version of safe_reverse that handles i18n edge cases.
6765
6866
Returns a lazy object that won't be evaluated until it's used as a string.
6967
"""

0 commit comments

Comments
 (0)