【问题标题】:forms ModelChoiceField queryset + extra choice fields django forms表单 ModelChoiceField 查询集 + 额外选择字段 django 表单
【发布时间】: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')]

我在这里做错了吗?

【问题讨论】:

    标签: django django-forms


    【解决方案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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-31
        • 2018-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-02
        • 1970-01-01
        • 2016-12-20
        相关资源
        最近更新 更多