【发布时间】:2016-06-08 09:55:07
【问题描述】:
在 Django 1.9 中,我基于与 forms.py 中的 TheModel 对应的数据库表构建表单列表。当数据库表发生变化时,我希望表单也发生变化。因此我设置了一个 Django 信号来监听变化并更新表单。我现在的问题是信号处理程序无法真正返回任何内容,因此我需要以global 变量的形式访问表单列表。由于使用global 通常被认为是不好的做法:是否有更好的解决方案或者在这种情况下使用global 是否可以接受?
这是我在views.py中的代码:
from django.dispatch import receiver
from django.db.models.signals import post_save, post_delete
from .forms import construct_forms
# Init container for forms.
forms = construct_forms()
# Be aware that this signal is firiing twice for some reason.
@receiver((post_save, post_delete), sender=TheModel, dispatch_uid='change')
def reconstruct_forms(sender, **kwargs):
"""
Reconstruct forms if model was changed.
"""
# Use global variable so `forms` will be available in
# updated version later on.
global forms
forms = construct_forms()
print('Model was changed, forms are reconstructed.')
def some_view(request):
# Do something with the forms
重要修改:
当我问这个问题时,我完全不知道信号只在正在运行的生产服务器的一个线程中工作。因此,像这样的方法,使用信号来更新内存变量将最终导致服务器上的一个线程显示更新的表单,而其余的,信号没有到达的地方,将显示一个过时的版本。当然,这在生产中是不可接受的。如果确实需要缓存,您应该查看有关缓存的Django docs。对于我的小表单构造来说,它实际上是矫枉过正的。我将把这个问题留给正确的方向。请不要尝试以我的方式实现!
【问题讨论】:
-
ekhm... 更改表(结构)或更改数据?以及为什么需要在数据更改后重建表单?
-
这将因带有多个线程或进程的 bing bang 失败......也就是生产部署:(
-
假设我有一个选择小部件,其中包含来自表格列的所有不同选项。如果添加了某些内容,我希望这反映在下一次加载表单时,但由于数据很少更改,我想缓存表单。
-
你能解释一下吗?或者指出资源是否已经解释?
-
所以你使用分布式缓存(memcache.redis)并在那里存储一个 list 选项,然后在“save”或信号处理程序中更新外部缓存,你可以不触摸表单的定义,您只需从表单的 init 中的缓存加载数据
标签: python django django-signals