Opened 11 months ago
Last modified 11 months ago
#35985 closed Cleanup/optimization
SCRIPT_NAME / FORCE_SCRIPT_NAME ignored when running reverse() on non-main thread — at Initial Version
| 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
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 hc.urls.base._prefix 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.