如何在__init__中的模型框架上将字段的窗口小部件切换为“选择”?

时间:2015-05-07 01:04:39

标签: django forms

我需要为管理员创建一个使用不同小部件的表单,而不是常规用户使用的表单。管理员可以为网站上的任何用户添加BillingAccount,而普通用户只能为自己添加一个。

这是我的基本表单类定义:

class BillingAccountForm(forms.ModelForm):

    class Meta:
        model = BillingAccount
        fields = '__all__'
        widgets = {
            # Under most circumstances, the observer field should be hidden,
            # because it's automatically set up to be the current user.
            'observer': forms.HiddenInput()
        }

对于管理员,我希望Observer字段提供数据库中所有UserProfile的下拉列表,而不是隐藏它。我试过这个:

def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=None,
            error_class=ErrorList, label_suffix=None, empty_permitted=False, instance=None,
            form_type='edit'):
    """
    This constructor changes up the widgets offered based on the form_type argument.
    """

    super(BillingAccountForm, self).__init__(
        data, files, auto_id, prefix, initial, error_class, label_suffix, empty_permitted, instance
    )

    if form_type == 'admin':
        self.fields['observer'].widget = widgets.Select(
            choices=UserProfile.objects.order_by('user__last_name', 'user__first_name').all()
        )

但由于一些奇怪的原因,它给了我一个填充了空白选项的<select>列表。我得到了正确的数字选项,但它们都是空字符串。

1 个答案:

答案 0 :(得分:0)

当我写这篇文章时,侧边栏中出现的一个“类似问题”给了我答案。问题是切换字段的小部件是不够的:您还需要更改字段的查询集

def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=None,
            error_class=ErrorList, label_suffix=None, empty_permitted=False, instance=None,
            form_type='edit'):
    """
    This constructor changes up the widgets offered based on the form_type argument.
    """

    super(BillingAccountForm, self).__init__(
        data, files, auto_id, prefix, initial, error_class, label_suffix, empty_permitted, instance
    )

    if form_type == 'admin':
        self.fields['observer'].widget = widgets.Select()
        self.fields['observer'].queryset = UserProfile.objects.order_by('user__last_name', 'user__first_name')

我不知道为什么这是必要的。该字段已经有一个queryset属性,所以我不知道重新分配它实际上是来修复空白选项。