【问题标题】:Django form updating after adding data to database将数据添加到数据库后更新 Django 表单
【发布时间】:2018-11-24 15:48:04
【问题描述】:

我正在为用户构建一个表单以在数据库上运行查询。该模型称为 Sample 并且用户正在选择他们想要包含在查询结果中的名称。在这种情况下,名称字段是唯一的,但以相同方式完成的其他字段则不是。

Form.py

from django import forms
from .models import Sample

class SampleForm(forms.Form):
    samples = Sample.objects.all()
    names = [(s.id, s.name) for s in samples]
    initial = [c[0] for c in names]
    Rock_Names = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,
                                          choices=names,
                                          initial=initial,
                                          label='Name')

我遇到的问题是,添加新样本后,在我重新启动服务器之前,表单不会使用该样本名称更新。我有一个所有样本的列表视图,它会随着新样本的更新而更新。在保存新样本后,我尝试运行Sample.objects.update(),但这并没有帮助。有没有办法强制更新?有没有更好的方法来构建查询表单?

编辑 好的,我想通了,意识到这是一个更基本的面向对象编程问题。表单是使用类定义定义的类属性创建的(在服务器重新启动时),而不是在创建实例时(当页面重新加载时)。我不认为我想在每次页面加载时重新运行表单创建(例如移动到 init 方法中的实例属性),所以我将表单创建移动到在类定义中调用的函数并通过我的方法添加数据时可以调用。新代码如下所示:

from django import forms
from .models import Sample

def create_form():
    samples = Sample.objects.all()
    names = [(s.id, s.name) for s in samples]
    initial = [c[0] for c in names]
    Rock_Names = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,
                                          choices=names,
                                          initial=initial,
                                          label='Name')
    return Rock_Names

class SampleForm(forms.Form):
    Rock_Names = create_form()

   def update_form():
      Rock_Names = create_form()

【问题讨论】:

    标签: django django-models django-forms


    【解决方案1】:

    当您有一个包含动态选项的选项字段时,建议将它们设置在 __init__ 方法中。

    在您的情况下,您可以简单地使用ModelMultipleChoiceField 而不是MultipleChoiceField

    class SampleForm(forms.Form):
    
        rock_names = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,
                                              queryset=Sample.objects.all(),
                                              label='Name')
    

    要获得Sample.name 作为标签,您必须给Sample 一个__str__ 方法:

    class Sample(models.Model):
    
        ...
    
        def __str__(self):
            return self.name
    

    或者通过自定义label_from_instance 方法创建和使用ModelMultipleChoiceField 的子类:

    class SampleMultipleChoiceField(MultipleChoiceField):
    
        def label_from_instance(self, obj):
            return obj.name
    
    
    class SampleForm(forms.Form):
    
        rock_names = SampleMultipleChoiceField(widget=forms.CheckboxSelectMultiple,
                                              queryset=Sample.objects.all(),
                                              label='Name')
    

    顺便说一句,常见的约定是将类属性写成小写。

    【讨论】:

      猜你喜欢
      • 2015-08-15
      • 1970-01-01
      • 2013-02-27
      • 1970-01-01
      • 1970-01-01
      • 2015-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多