Skip to content

Conversation

foarsitter
Copy link
Contributor

The cached.Loader template loader is default in Django 4.1, even with DEBUG=True.

To take advantage of this loader in development the runserver command is extended to invalidated the cache when an template is changed.

runserver_plus does not listen to changes in .html and does not invalidate the template cache on change.

This pull requests adds the .html suffix to extra_files so the Werkzeug reloader fires the correct signals. By firing the django.utils.autoreload.file_changed event on each change the django.template.autoreload.template_changed receiver can trigger reset_loaders when needed.

Fixes #1766

@foarsitter
Copy link
Contributor Author

The actions fail due to #1777

@trbs trbs merged commit 868b8a8 into django-extensions:main Dec 25, 2022
@foarsitter
Copy link
Contributor Author

@trbs thanks for mergin. Is there something of a schedule for a new release? A new release would make it possible for cookiecutter/cookiecutter-django#4028 to upgrade to Django 4.1.

@foarsitter
Copy link
Contributor Author

@trbs or someone else do you have some spare time for a release?

@bmihelac
Copy link
Contributor

Hello everyone! I have just tried django-extensions from git and it looks like that this patch does not trigger template reload. Digging through werkzeug code it looks to me that extra_files is for files and not for patterns, see https://github.com/pallets/werkzeug/blob/main/src/werkzeug/_reloader.py#L76-L77

@foarsitter
Copy link
Contributor Author

@bmihelac extra_files is added to the patterns over here: https://github.com/pallets/werkzeug/blob/main/src/werkzeug/_reloader.py#L328

Can you tell me more about your setup? How does your template loader settings look like? Do you use the StatReloader?

@bmihelac
Copy link
Contributor

@foarsitter thanks for your time.

I believe that template loaders are standard from what you get when you start new project + DIRS:

 TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [
            BASE_DIR / "templates",
        ],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
            ],
        },
    },
]

If extra-file argument is similar to what this patch is doing, here is the easiest way to reproduce this.

./manage.py runserver_plus --extra-file="*.html"

Changing test.html with this command would not trigger reloading.

./manage.py runserver_plus --extra-file="test.html" 

Changing test.html with this would reload and it is visibile in console.

 * Detected change in '.../test.html', reloading
 * Restarting with stat

let me know if you need any more information.

@foarsitter
Copy link
Contributor Author

The template reload does reset the cache of the cached.loader, it does not restart werkzeug. So there is no trace in the logs.

But the evidence you provide is strong.

I verified the patch and here it works like a charm. Im on Linux using Docker, using the statloader and Django 4.1

How do you install the main branch through pip? What OS you are on?

@bmihelac
Copy link
Contributor

I am on linux, Django 4.1, stat reloader, installed django-extensions with:

pip install git+https://github.com/django-extensions/django-extensions

I have tried once more right now and cached template is displayed.

@foarsitter
Copy link
Contributor Author

Do you have time to craft a minimal viable project and share it on GitHub? Currently Im on holiday but next week I can dive into it.

@bmihelac
Copy link
Contributor

@foarsitter sure, i'll create test project for this ASAP

@foarsitter
Copy link
Contributor Author

foarsitter commented Jan 24, 2023

@bmihelac you are right about that the StatReloaderLoop does not work. Somehow I was using WatchdogReloaderLoop which gives the desired results.

werkzeug._reloader._find_stat_paths should be patched or we need to add all the template files to extra_files. What do you think is the desired solution?

Update: something like this seems to work: main...foarsitter:django-extensions:runserver_plus_autoreload_templates_statloader

@bmihelac
Copy link
Contributor

@foarsitter what do you think about using dango.template.autoreload.get_template_directories to simplify getting template directories?

I wonder about the case of adding new templates after dev server is started - would they be watched or extra_files list is created only when server starts?

@foarsitter
Copy link
Contributor Author

@bmihelac my attempt to mimic get_template_directories is indeed a poor one. Thanks for pointing me to the existence of that method.

runserver detects the addition of new files, my proposal does not. So that is a problem.

@foarsitter
Copy link
Contributor Author

If extra-file argument is similar to what this patch is doing, here is the easiest way to reproduce this.

./manage.py runserver_plus --extra-file="*.html"

This brought my on an idea to create a workaround except each --extra-file is wrapped with os.path.abspath so only .html in the root directory is watched.

@danjesus
Copy link

I'm having the same problem here, changes to templates don't trigger a change event.

Only when using the default runserver.

Anyone else with same problem?

@foarsitter foarsitter deleted the runserver_plus_autoreload_templates branch November 21, 2023 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[runserver_plus] autoreload django
4 participants