使用Django的get_form_kwargs修改form.exclude[]?

0 投票
1 回答
1012 浏览
提问于 2025-04-18 14:30

我有一个模型,它有一些选项可以控制表单的显示方式。比如说,自动生成客户ID。目前我定义了两个表单,它们完全一样,唯一的不同在于排除列表,而这个排除列表只在客户ID字段上有所不同。

我原本以为可以通过get_form_kwargs来修改这个,但看起来并没有按我想的那样工作。

有没有办法实现这个功能,还是说我只能使用两个不同的表单?这样不太符合“不要重复自己”的原则。


get_form_kwargs

def get_form_kwargs(self):
    kwargs = super(CustomerCreateView, self).get_form_kwargs()

    if not self.request.user.company.generate_account_numbers:
        kwargs['exclude'].extend('customer_id')
    return kwargs

1 个回答

2

exclude选项是由metaclass使用的,目的是在类定义的时候,防止某些模型字段被生成成表单字段。也就是说,一旦类定义完成后,改变这个选项是没有任何效果的。

get_form_kwargs提供了创建表单实例所需的参数。根据定义,类在提供表单参数之前就已经定义好了,所以在表单参数中改变exclude是没有用的。

一个解决办法是重写__init__方法,如果传入了某个参数,就手动移除已经生成的customer_id字段。

class CustomerForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        exclude_customer_id = kwargs.pop(exclude_customer_id, False):
        super(CustomerForm, self).__init__(*args, **kwargs)
        if exclude_customer_id:
            del self.fields['customer_id']

你需要考虑一下,额外的__init__代码是否值得,以避免创建两个表单类。

撰写回答