【问题标题】:Django: form values not updating when model updatesDjango:模型更新时表单值不更新
【发布时间】:2009-09-30 15:14:17
【问题描述】:

我正在创建一个使用 MultipleChoiceField 的表单。该字段的值来自另一个模型。此方法工作正常,但是,我注意到(在生产服务器上)当我向相关模型(NoticeType)添加新项目时,表单不会动态更新。我必须重新启动服务器才能让新项目显示在我的 MultipleChoiceField 上。

对 NoticeType 模型的任何更改(编辑项目或创建新项目)都不会传播到表单。重新启动生产服务器后,会出现更新。

任何想法为什么会这样?表格的相关部分如下。谢谢。

from django import forms 
from django.contrib.auth.models import User
from notification.models import NoticeType

class EditUserProfileForm(forms.Form):   
    CHOICES = []

    for notice in NoticeType.objects.all():
        CHOICES.append( (notice.label,notice.display) )

    notifications   = forms.MultipleChoiceField(
                        label="Email Notifications",
                        required=False,
                        choices=( CHOICES ),
                        widget=forms.CheckboxSelectMultiple,)

【问题讨论】:

    标签: python django django-forms


    【解决方案1】:

    虽然 mherren 是正确的,您可以通过在 __init__ 方法中定义您的选择来解决此问题,但还有一种更简单的方法:使用专门设计用于获取查询集并动态更新的 ModelMultipleChoiceField

    class EditUserProfileForm(forms.Form):
        notifications = forms. ModelMultipleChoiceField(
                        label="Email Notifications",
                        required=False,
                        queryset = NoticeType.objects.all(),
                        widget=forms.CheckboxSelectMultiple)
    

    【讨论】:

    • 那更性感!而且我认为它不能变得更好 - 谢谢。将进行调整以节省我的代码库中的一些宝贵空间。谢谢。
    • 使用这种技术,我还能指定哪个模型字段在表单上显示为“文本”吗?
    • 默认情况下它使用__unicode__ 表示。如果您需要不同的东西,则需要继承 ModelMultipleChoiceField 并覆盖 label_from_instance,如下所述:docs.djangoproject.com/en/dev/ref/forms/fields/…
    • 谢谢 - 我想我可能会走那条路,因为我认为这似乎是“django”想要的方式。我是 stackoverflow 的新手——我应该在完成后将我的最终“工作”代码作为“答案”发布吗?
    • @DanielRoseman 谢谢label_from_instance!帮了大忙。
    【解决方案2】:

    我的直觉是类定义只在加载时处理一次,而不是每次实例化。尝试将 CHOICES 计算添加到 init 方法中,如下所示:

    def __init__(self, *args, **kwargs):
        super(self.__class__, self).__init__(*args, **kwargs)
        CHOICES = []
        for notice in NoticeType.objects.all():
            CHOICES.append( (notice.label, notice.display) )
        self.fields['notifications'].choices = CHOICES
    

    【讨论】:

    • 嘿!太好了 - 立即修复它。在我发布之后,我有一个类似的想法,实际上,但没有考虑__init__() 方法......我想我可以在返回列表的类之外创建一个新函数......但我更喜欢这个。谢谢!
    猜你喜欢
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-13
    • 2021-09-27
    • 2016-12-30
    • 2021-05-26
    • 1970-01-01
    相关资源
    最近更新 更多