形成ModelChoiceField查询集+额外选择字段django表单

时间:2011-03-12 07:12:38

标签: django django-forms

我正在尝试创建一个表单,其中ModelChoiceField从queryset加载,我想向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')]

我在这里做错了吗?

3 个答案:

答案 0 :(得分:15)

那不行。看看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

答案 1 :(得分:3)

您似乎只想允许这些表单字段是可选的。不要让自己变得困难。有关根据需要标记表单字段,请参阅the documentation

lead = forms.ModelChoiceField(queryset=People.objects.filter(poc__in=('lead', 'sr.lead')), required=False)

答案 2 :(得分:1)

你有一个pk'无'的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")

编辑:

由于您使用的是modelchoicefield,我认为您的所有选择都可以是该模型类型,也可以不是。

您可以通过修改传递给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?