我正在建立一个供用户在数据库上运行查询的表单。该模型称为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()
答案 0 :(得分:2)
当您拥有带有动态选择的选择字段时,建议使用__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
或通过自定义的ModelMultipleChoiceField
方法创建并使用label_from_instance
的子类:
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')
顺便说一句,通用约定是用小写形式编写类属性。