#35985 closed Cleanup/optimization (wontfix)
FORCE_SCRIPT_NAME ignored when running reverse() on non-main thread — at Version 2
Reported by: | Pēteris Caune | Owned by: | |
---|---|---|---|
Component: | Core (URLs) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Florian Apolloner | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
I've configured my Django project to run on a subpath (under example.org/some_prefix
instead of example.org
).
The project has a management command which generates URLs using django.urls.reverse()
.
Since the management command cannot read SCRIPT_NAME from WSGI parameters, the project has FORCE_SCRIPT_NAME = "/some_prefix"
in settings.py.
The management command generates URLs that include the prefix as expected if the code runs on main thread. But if the management command spawns a thread, the code running on thread generates URLs without the prefix.
I'm not sure but I think this is related to django.urls.base._prefixes
being a Local
object. I'm guessing it, as the name suggests, does not share data between threads. Even though set_script_prefix
is called on main thread, the other threads do not see it.
A simple workaround is for the user to call set_script_prefix
by themselves:
from django.conf import settings from django.urls import set_script_prefix def this_will_be_run_on_thread(): if settings.FORCE_SCRIPT_NAME: set_script_prefix(settings.FORCE_SCRIPT_NAME) # do work here
But perhaps there's something Django could do here as well:
- perhaps, change django.urls implementation so that threads do share the script prefix storage?
- if there are disadvantages to that, mention this gotcha in the documentation
I'm happy to provide a dummy project demonstrating the issue if that would be helpful.
Change History (2)
comment:1 by , 9 days ago
Cc: | added |
---|---|
Resolution: | → wontfix |
Status: | new → closed |
Type: | Bug → Cleanup/optimization |
Version: | 5.1 → dev |
comment:2 by , 9 days ago
Description: | modified (diff) |
---|---|
Summary: | SCRIPT_NAME / FORCE_SCRIPT_NAME ignored when running reverse() on non-main thread → FORCE_SCRIPT_NAME ignored when running reverse() on non-main thread |
Hello Pēteris Caune, thank you for taking the time to create this report. I have read your description carefully and I yes, I agree, the fact that
_prefixes
is local to the thread means that spawned threads will not share its contents. Also the functionset_script_prefix
has this docstring:For a workaround, Django will set the prefix when
setup
is called, perhaps the best option for your management command is to callsetup
in each thread? Feels cleaner and more correct.Regarding your comment for change django.urls implementation so that threads do share the script prefix storage, in my opinion this is beyond to what the main goal of Django is. As shown above, this is simple to add/solve to your code base, and to me this is a very specific need arising from a niche use case. I don't think this applies to the broader ecosystem, and Django is a framework designed to offer robust and accurate solutions for common scenarios.
Given the above, I'll close the ticket accordingly, but if you disagree, you can consider starting a new conversation on the Django Forum, where you'll reach a wider audience and likely get extra feedback.