Mod_wsgi on Python 3.10 does not update Django templates without Apache restart

I have been running a Django server on Python 3.8 with Apache and mod_wsgi for some time now, and decided it was time to upgrade to Python 3.10. I installed Python 3.10 on my server, installed the Django and mod_wsgi packages, copied the 3.10 build of to Apache's modules folder, and everything works great ... however, it seems with this build of mod_wsgi, changes to template files do not take effect unless I restart Apache.

As an example, I added a random HTML template file to my website, and started the server with some initial text in that template. Running on the Python 3.8, I am able to change the contents of that template (e.g. echo "More Text" >> test_template.html) and upon refreshing my browser the new text will show up. However doing the same test in 3.10, the new text will not show up. I have tried different browser sessions and hard reloading, it is not a caching issue on the client side, and looking at the response sizes in Apache's access log confirms the data being sent to the client changes in 3.8 but not in 3.10.

I have stood up a test server to isolate the problem, and have narrowed it down to specifically changing the mod_wsgi build (which of course changes the entire Python version used by Django). Still, that confirms it should not be a caching setting of Apache, or any mis-configuration of Django templates, and I have followed the steps here to confirm I am running mod_wsgi in Daemon mode (as I have been for years on this server, this is a long-standing server configured seemingly without issue for Python 3.8).

Lastly, running the Django development server (using base runserver command) reflects template changes on the fly without issue, and without a server reboot. So as far as I can tell this seems to be a mod_wsgi quirk.

The specific Apache | mod_wsgi | Python version combinations is as follows:

Apache/2.4.41 (Ubuntu) mod_wsgi/4.6.8 Python/3.8

Apache/2.4.41 (Ubuntu) mod_wsgi/4.9.4 Python/3.10 reported by Apache's error.log, confirming the modules are loading as expected.

Does anyone know if this is a known issue with Python 3.10 builds of mod_wsgi? Perhaps is there a new setting I'm forgetting? My understanding of Django templates is that they should always reflect changes immediately (without a server restart), however code changes require a restart (or touching of the script); I have never had to restart the server for template changes prior to this change. Any help is appreciated-

The issue you are encountering with changes to Django templates not taking effect unless you restart Apache after upgrading to Python 3.10 with mod_wsgi 4.9.4 could be due to a compatibility issue between the new Python version and mod_wsgi. As mod_wsgi is a Python module that provides a WSGI interface for hosting Python web applications like Django, it's possible that changes to the Python environment (e.g., Python version upgrade) can cause changes to how mod_wsgi behaves.

I would recommend checking the mod_wsgi documentation and release notes for any compatibility issues related to Python 3.10, as well as any changes to the mod_wsgi configuration required to support the new Python version.

Additionally, you can try running your Django application with mod_wsgi in the "embedded" mode, as this will allow you to test the Python environment and any related issues without involving Apache. To do this, you can modify your WSGI script to run in embedded mode, as described in the mod_wsgi documentation. This will allow you to isolate the issue and determine if it is specific to mod_wsgi or to your Apache setup.

I ended up making a post under the mod_wsgi github project, and traced the issue back to a change in Django's behavior in this commit

Full details of that post can be found here

Tl;dr; is there is a caching template loader, which used to only be enabled when DEBUG = False was set, but was updated to always be in effect. I'm not sure why my Python 3.8 build did not have this change, as I had upgraded both builds to the latest Django build available (4.6.1), but my original install was years ago so it's quite possible a fresh install would not have had this issue.

If you still want to disable cached templates as I did, you have to override the template loaders in your Django settings:

        'OPTIONS': {
            'loaders': ['django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader']
Back to Top