class StatusForm(ModelForm):
bases = forms.ModelMultipleChoiceField(
queryset=Base.objects.all(), #this should get overwritten
widget=forms.SelectMultiple,
)
class Meta:
model = HiringStatus
exclude = ('company', 'date')
def __init__(self, *args, **kwargs):
super(StatusForm, self).__init__(*args, **kwargs)
if kwargs.has_key('bases_queryset'):
self.fields['bases'].queryset = kwargs['bases_queryset']
我想在此表单中添加一个选项,允许我创建一个这样的表单:
form = StatusForm(bases_queryset=Base.objects.filter([...])
但我不知何故需要在该类中“添加”该关键字参数,以便识别它。他们现在的方式,我只是得到这个错误:
__init__() got an unexpected keyword argument 'bases_queryset'
答案 0 :(得分:11)
那是因为你正在将kwargs解包给超级构造函数。 在调用super之前尝试将其放入:
if kwargs.has_key('bases_queryset'):
bases_queryset = kwargs['bases_queryset']
del kwargs['bases_queryset']
但这不是一个理想的解决方案......
答案 1 :(得分:11)
如@Keeper所示,您不得将“new”关键字参数传递给超类。在你打电话给超级__init__
:
bqs = kwargs.pop('bases_queryset', None)
在__init__
电话之后,请检查if bqs is not None:
,而不是使用has_key
(当然,请使用bqs
代替kwargs['bases_queryset']
。
一种有趣的替代方法是进行“选择性调用”高阶函数。如果你同时拥有位置和命名参数(那些总是对于元程序来说有点混乱;-),这有点乱,所以为了简化说明,假设你想要选择性地调用的函数只有“普通的“命名参数(即没有**k
)。现在:
import inspect
def selective_call(func, **kwargs):
names, _, _, _ = inspect.getargspec(func)
usable_kwargs = dict((k,kwargs[k]) for k in names if k in kwargs)
return func(**usable_kwargs)
使用这种方法,在__init__
中,而不是直接调用超级__init__
,你会打电话
selective_call(super_init, **kwargs)
让这个高阶函数执行所需的“修剪”。 (当然,你将需要使处理位置和命名args变得更加混乱,啊...... - )