模块变量似乎与进程一样存在,并且在进程重新启动之前不会重置。
这是我的代码,我希望它的行为方式与现在的行为方式不同:
我有一个模块负责各种 SEO 功能,例如面包屑和标题,文件 fancy/utils.py:
class Seo:
title = ['project name']
稍后在我的视图中,我可以将项目添加到 Seo.title(例如 news.views):
from fancy.utils import Seo
def index(request, news_id):
title.append('some specific title')
...
重点是变量 Seo.title 实际上不会在每次请求时重置,因此它继续向自身追加项目,这对我来说看起来很奇怪(因为我来自 PHP)。
最终,如果我在同一页按 F5,标题总是会变得又大又长。
发生了什么事,我应该做什么?
谢谢
从你的评论看来你完全误解了Django的执行模型。
您无法拥有可以从代码中的任何位置访问的请求本地数据。如果您需要与特定请求关联的数据,则应该将其存储在运行该请求的代码可以检索它的位置:也许在会话中,也许在添加到请求对象本身的临时字典中。您全局存储的任何内容都将是全局的:对同一进程内运行的任何请求都可见。
您的
title
是一个类属性,而不是 instance
属性。如果您想在多个请求中保留设置,您可以在会话中保留对其的引用。
例如
class Seo(object):
def __init__(self):
self.title = ['project name']
...
def index(request, news_id):
seo = request.session.get('seo', Seo())
seo.title.append('some specific title')
这似乎是对 Django 如何执行代码的一些误解。 Django 作为 WSGI / ASGI 应用程序运行。开发服务器 (
manage.py runserver
) 或生产服务器启动 Python 进程,只要有请求,它们就会传递到应用程序。
这些进程可用于服务多个请求,并且在请求之间不会卸载/清除任何全局变量、模块等(这允许开发人员实现内存缓存等功能)。
你的
Seo
类可以说是一个全局变量,而 title
是它的类属性。因此,当您改变 title
列表时,它将在请求中持续存在。使值不持久的一种解决方案是使 title
成为一个实例属性,并在任何需要的请求上实例化 Seo
(这是一种模式,基于类的视图也遵循这种模式,as_view
方法返回一个函数实例化该类使其透明)。