Django 在多个请求期间不会重置模块变量

问题描述 投票:0回答:3

模块变量似乎与进程一样存在,并且在进程重新启动之前不会重置。

这是我的代码,我希望它的行为方式与现在的行为方式不同:

我有一个模块负责各种 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,标题总是会变得又大又长。

发生了什么事,我应该做什么?

谢谢

python django django-views
3个回答
3
投票

从你的评论看来你完全误解了Django的执行模型。

您无法拥有可以从代码中的任何位置访问的请求本地数据。如果您需要与特定请求关联的数据,则应该将其存储在运行该请求的代码可以检索它的位置:也许在会话中,也许在添加到请求对象本身的临时字典中。您全局存储的任何内容都将是全局的:对同一进程内运行的任何请求都可见。


1
投票

您的

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')

0
投票

这似乎是对 Django 如何执行代码的一些误解。 Django 作为 WSGI / ASGI 应用程序运行。开发服务器 (

manage.py runserver
) 或生产服务器启动 Python 进程,只要有请求,它们就会传递到应用程序。

这些进程可用于服务多个请求,并且在请求之间不会卸载/清除任何全局变量、模块等(这允许开发人员实现内存缓存等功能)。

你的

Seo
类可以说是一个全局变量,而
title
是它的类属性。因此,当您改变
title
列表时,它将在请求中持续存在。使值不持久的一种解决方案是使
title
成为一个实例属性,并在任何需要的请求上实例化
Seo
(这是一种模式,基于类的视图也遵循这种模式,
as_view
方法返回一个函数实例化该类使其透明)。

© www.soinside.com 2019 - 2024. All rights reserved.