Django部署应用中全局变量设置后自动恢复初始值问题求助
问题根源分析
你猜的完全没错!Django部署在服务器上时,模块级的全局变量(比如你在views.py里定义的w_m = "xxx")确实会因为进程特性被重置:
- 服务器通常用WSGI服务器(比如Gunicorn、uWSGI)启动多个worker进程处理请求,每个进程都会独立加载一次
views.py,所以每个进程都有自己的w_m副本。你通过表单设置的只是某个进程里的w_m值,其他进程的w_m还是初始的"xxx"。 - 另外,WSGI服务器会定期重启worker进程(比如资源回收、代码热重载),进程重启时
views.py会重新加载,w_m就会被打回初始值。
靠谱的解决方案
下面给你几种生产环境可用的方案,按推荐程度排序:
1. 用数据库存储全局变量(最推荐)
数据库是所有进程共享的持久化存储,不管进程怎么重启,值都会稳定保留。
步骤1:创建全局设置模型
在你的models.py里添加一个模型来存储全局配置:
from django.db import models class GlobalSetting(models.Model): # 用key区分不同的全局变量 key = models.CharField(max_length=50, unique=True) value = models.CharField(max_length=255) @classmethod def get_w_m(cls): # 不存在就自动创建默认值"xxx" setting, _ = cls.objects.get_or_create(key='w_m', defaults={'value': 'xxx'}) return setting.value @classmethod def set_w_m(cls, new_value): setting, _ = cls.objects.get_or_create(key='w_m', defaults={'value': 'xxx'}) setting.value = new_value setting.save()
步骤2:迁移数据库
执行以下命令让Django创建对应的数据库表:
python manage.py makemigrations python manage.py migrate
步骤3:修改视图代码
把原来的全局变量逻辑替换成数据库操作:
from .models import GlobalSetting from .forms import admin_form def admin_setbasedata(request): form_ = admin_form() if request.method == "POST" and "set_w" in request.POST: new_w_m = request.POST.get('serial') # 保存到数据库 GlobalSetting.set_w_m(new_w_m) # 以后要获取w_m的值,就调用这个方法 current_w_m = GlobalSetting.get_w_m() # ... 其他业务逻辑
2. 用缓存系统存储(适合临时全局变量)
如果你的w_m不需要持久化(服务器重启后丢失也能接受),可以用Django的缓存框架,比如Redis或Memcached,它们是跨进程共享的存储。
步骤1:配置缓存
以Redis为例,先安装依赖django-redis,然后在settings.py里配置:
CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': 'redis://127.0.0.1:6379/1', 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient', } } }
步骤2:修改视图代码
from django.core.cache import cache from .forms import admin_form def get_w_m(): # 缓存里没有值就返回默认的"xxx" return cache.get('w_m', 'xxx') def admin_setbasedata(request): form_ = admin_form() if request.method == "POST" and "set_w" in request.POST: new_w_m = request.POST.get('serial') # 保存到缓存,timeout设为None表示永不过期 cache.set('w_m', new_w_m, timeout=None) current_w_m = get_w_m() # ... 其他业务逻辑
3. 绝对要避开的方案
- 别再用模块级全局变量:进程隔离和重启的问题根本没法解决。
- 不要动态修改
settings.py:修改后必须重启服务器才生效,还会污染版本控制里的配置文件。
内容的提问来源于stack exchange,提问作者ali
相关产品推荐
相关产品推荐

