如何让Django在模板改变时重新启动runserver?

sz81bmfz  于 2023-02-05  发布在  Go
关注(0)|答案(8)|浏览(308)

当我修改项目中的python源文件时,Django会检测到并重启runserver,但当我修改django模板时,我必须杀死runserver并重新启动它:如何使Runserver在模板更改时自动重新启动?

nhjlsmyf

nhjlsmyf1#

默认情况下,每次请求时都会从磁盘读取该文件,因此无需重新启动任何操作。
有一个缓存模板加载器,但默认情况下是禁用的。更多信息请参见文档。

3lxsmp7m

3lxsmp7m2#

另一个解决方案是确保在settings.py中的TEMPLATES配置中将debug设置为true

DEBUG = True

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['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',
            ],
            'debug': DEBUG,
        },
    },
]

debug为False时,您必须手动重启服务器才能查看对模板所做的任何更改(因为它们不会自动触发重启)

fkaflof6

fkaflof63#

对其中一个Python源文件运行touch
因为runserver监视.py文件的更改,所以它不会因为模板(.html)中的更改而重新启动。您可以通过使用touch命令虚拟编辑任何.py文件来触发这种重新启动,该命令刷新其修改日期并保持所有其他内容不变。

mrwjdhj3

mrwjdhj34#

为了补充knutin的回答,您所面临的问题正是由FetchFromCacheMiddleware引起的,因此您所需要做的就是在www.example.com文件中禁用它settings.py,如下所示:
settings.py:

MIDDLEWARE_CLASSES = (
    ...
    #'django.middleware.cache.FetchFromCacheMiddleware',
    ...
)
uinbv5nw

uinbv5nw5#

无需重新启动服务器即可重新加载模板更改。
在生产中,您可以执行以下操作:
在www.example.com中,对于模板配置settings.py, for the TEMPLATES config

  • 删除APP_DIRS设置
  • 而是将此设置添加到OPTIONS:
'loaders': [
  'django.template.loaders.filesystem.Loader',
  'django.template.loaders.app_directories.Loader',
],

为什么这样做:
DEBUG设置默认为True(在开发模式下)。在此模式下Django不缓存模板。但在生产模式下(即DEBUG = False)Django启用模板缓存。因此需要重新启动服务器来重新加载编辑过的模板。
注:
请注意这样一个事实--在生产机器上禁用模板缓存,您将为通过的每个请求增加开销。

zz2j4svz

zz2j4svz6#

我也遇到过类似的问题,但是我的模板需要一个django管理器脚本来更新它们。没有简单的方法可以让django监视其他文件类型,但是这里有一个我使用的解决方法。
这是我现在用来运行开发服务器的独立脚本:

#!/usr/bin/python

import time, subprocess, sys, os, re
from threading import Thread

run = True

def monitor():
  while run:
    os.system("./manage.py update_templates")
    os.system("touch website/urls.py")
    os.system("inotifywait -e modify,create,delete website/templates/*.html")

t = Thread(target=monitor)
t.start()
time.sleep(0.5)

args = ''
if len(sys.argv) > 1:
  for i in range( 1, len(sys.argv)):
    args += sys.argv[i] +' '
print("./manage.py runserver %s" % args)
os.system("./manage.py runserver %s" % args)
run = False
t.join()

此脚本在以下假设条件下工作:
1.使用python3
1.此脚本沿着www.example.com旁边manager.py

  1. manager.py 可运行
  2. Web应用程序称为网站
    1.该网站具有名为website/ www.example.com的文件urls.py
    1.您使用的是GNU/Linux,它支持inotify
63lcw9qa

63lcw9qa7#

文件将从磁盘读取,而无需重新启动runserver,只需确保禁用所有缓存。

禁用缓存模板加载程序

默认情况下缓存模板加载器是不启用的,但您可能已经在生产设置中启用了它。确保您的开发设置中没有启用缓存模板加载器。缓存模板加载器上的Django docs

使用虚拟缓存框架

当你使用django缓存框架时,这可能会导致模板无法重新加载。Django默认使用的缓存框架是本地内存缓存,这意味着你必须显式设置虚拟缓存来禁用缓存框架。

sg24os4d

sg24os4d8#

在更新的Django版本中:
默认情况下,缓存的模板加载程序是启用的,请参阅www.example.com:https://docs.djangoproject.com/en/4.2/ref/templates/api/#django.template.Engine :
loaders是指定为字符串的模板加载程序类的列表。每个加载程序类都知道如何从特定源导入模板。可以选择使用元组来代替字符串。元组中的第一项应该是加载程序类名,后续项在初始化期间传递给加载程序。
默认为包含以下内容的列表:

  • 'django.template.loaders.filesystem.Loader'
  • 'django.template.loaders.app_directories.Loader'当且仅当app_dirsTrue
    • 然后将这些装载机包裹在django.template.loaders.cached.Loader中。**

以及:
Django 4.1中的更改:在旧版本中,缓存模板加载器仅在DEBUGFalse时默认启用。
这意味着即使DEBUGTrue,仍然使用缓存的模板加载器
由于我不知道的原因,如果使用./manage.py runserver,则无论DEBUG值如何,每次仍然读取文件;而如果使用gunicorn mysite.wsgi:application./manage.py runserver_plus,则如预期地高速缓存文件。
无论如何,遵循this answer以便 * 不 * 在cached.Loader中 Package 加载器总是有效的。(您需要将选项添加到TEMPLATES.OPTIONS,它将传递给template.Engine--如果有app_dirs,请记住删除它)
另一种方法是添加到settings.py

INSTALLED_APPS = [
    'django_extensions',

然后运行例如

./manage.py runserver_plus  --extra-file polls/templates/polls/index.html

有关文档,请参见https://django-extensions.readthedocs.io/en/latest/runserver_plus.html

相关问题