表单 ModelChoiceField 查询集 + 额外选择字段 django 表单
Posted
技术标签:
【中文标题】表单 ModelChoiceField 查询集 + 额外选择字段 django 表单【英文标题】:forms ModelChoiceField queryset + extra choice fields django forms 【发布时间】:2011-07-13 23:08:22 【问题描述】:我正在尝试在从查询集加载的 ModelChoiceField 中创建一个表单,我想向 ModelChoiceField 添加一些自定义值以进行扩展,我使用了选择字段,如下所示,但在更新表单时,出现以下错误
表单错误: 选择一个有效的选项。该选择不是可用的选择之一。
代码:
self.fields['lead'] = forms.ModelChoiceField(queryset = Pepole.objects.filter(poc__in = ('lead','sr.lead')))
self.fields['lead2'] = forms.ModelChoiceField(queryset = Pepole.objects.filter(role__in = ('lead','sr.lead')))
choice_field = self.fields['lead']
choice_field.choices = list(choice_field.choices) + [('None', 'None')]
choice_field = self.fields['lead2']
choice_field.choices = list(choice_field.choices) + [('None', 'None')]
我在这里做错了吗?
【问题讨论】:
【参考方案1】:你有一个 pk 'None' 的 Person 对象吗?
我认为你应该使用
self.fields['lead'] = forms.ModelChoiceField(queryset = Pepole.objects.filter(poc__in = ('lead','sr.lead')), empty_label="None")
self.fields['lead2'] = forms.ModelChoiceField(queryset = Pepole.objects.filter(role__in = ('lead','sr.lead')), empty_label="None")
编辑:
由于您使用的是模型选择字段,我认为您的所有选择要么是该模型类型,要么没有。
您可以通过修改您传递给 modlechoicefield 的构造函数的查询集来“扩展”该类型的选择,例如:
qs = People.objects.filter(poc__in = ('lead','sr.lead'))
ext = People.objects.filter(role__in = ('lead', 'sr.lead'))
qs = qs | ext
self.fields['lead'] = forms.ModelChoiceField(queryset = qs, empty_label='None')
or for updating
self.fields['lead'].queryset = qs
这个问题稍微谈到了modelchoicefield,你可能会感兴趣:
How do I filter ForeignKey choices in a Django ModelForm?
【讨论】:
不,添加 empty_label="None" 后它也不起作用。这里我的问题是将选择从查询集扩展到选择选项【参考方案2】:那是行不通的。看看ModelChoiceField
是如何工作的:
try:
key = self.to_field_name or 'pk'
value = self.queryset.get(**key: value)
except self.queryset.model.DoesNotExist:
raise ValidationError(self.error_messages['invalid_choice'])
return value
你不能随意添加一些东西。
改用ChoiceField
并自定义处理数据。
class TestForm(forms.Form):
mychoicefield = forms.ChoiceField(choices=QS_CHOICES)
def __init__(self, *args, **kwargs):
super(TestForm, self).__init__(*args, **kwargs)
self.fields['mychoicefield'].choices = \
list(self.fields['mychoicefield'].choices) + [('new stuff', 'new')]
def clean_mychoicefield(self):
data = self.cleaned_data.get('mychoicefield')
if data in QS_CHOICES:
try:
data = MyModel.objects.get(id=data)
except MyModel.DoesNotExist:
raise forms.ValidationError('foo')
return data
【讨论】:
【参考方案3】:您似乎只想允许这些表单字段是可选的。不要让自己难受。请参阅the documentation,了解如何根据需要标记表单域。
lead = forms.ModelChoiceField(queryset=People.objects.filter(poc__in=('lead', 'sr.lead')), required=False)
【讨论】:
以上是关于表单 ModelChoiceField 查询集 + 额外选择字段 django 表单的主要内容,如果未能解决你的问题,请参考以下文章
带有modelchoicefield的Django多个表单->查询太多
如何在 ModelChoiceField 中使用多个查询集?