Django:关键字参数'initial'的多个值

时间:2013-10-30 01:09:08

标签: python django

在Django上我得到了这个追溯:

File "/Users/eeytan/ddragon/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  115.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Users/eeytan/ddragon/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper
  372.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/eeytan/ddragon/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "/Users/eeytan/ddragon/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  89.         response = view_func(request, *args, **kwargs)
File "/Users/eeytan/ddragon/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
  202.             return view(request, *args, **kwargs)
File "/Users/eeytan/ddragon/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
  25.             return bound_func(*args, **kwargs)
File "/Users/eeytan/ddragon/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "/Users/eeytan/ddragon/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
  21.                 return func(self, *args2, **kwargs2)
File "/Users/eeytan/ddragon/lib/python2.7/site-packages/django/db/transaction.py" in inner
  223.                 return func(*args, **kwargs)
File "/Users/eeytan/ddragon/lib/python2.7/site-packages/django/contrib/admin/options.py" in change_view
  1085.             form = ModelForm(request.POST, request.FILES, instance=obj)

Exception Type: TypeError at /admin/dragon_portal/parentprofile/1/
Exception Value: __init__() got multiple values for keyword argument 'instance'

此代码基于Creating one Django Form to save two models

class ParentCreationForm(UserCreationForm):
    first_name  = forms.CharField(max_length=100)
    last_name   = forms.CharField(max_length=100)
    email       = forms.EmailField()
    #ice_contact = forms.CharField(max_length=100)
    #notes       = HTMLField()

    def __init__(self, instance=None, *args, **kwargs):
        _fields = ('username', 'first_name', 'last_name', 'email', 'password')
        _initial = model_to_dict(instance.dragonuser, _fields) \
            if instance is not None else {}
        kwargs['initial'] = _initial
        super(ParentCreationForm, self).__init__(instance=instance, *args, **kwargs)
        self.fields.update(fields_for_model(DragonUser, _fields))

如您所见,__init__()的签名未更改。另外,更奇怪的是,Django更详细的追溯显示,对于追溯中的每一步,argv 总是{},所以我甚至不确定在什么时候错误来自的追溯。

2 个答案:

答案 0 :(得分:1)

ModelForm的__init__函数签名不正确。

Django source for BaseModelForm您可以看到函数签名是:

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):

因此,如果有人在Django的第一个位置用一个未命名的参数实例化你的表单,那么你最终会得到这个错误。

我建议像这样重写__init__

 def __init__(self, *args, **kwargs):
        instance = kwargs.get('instance')
        _fields = ('username', 'first_name', 'last_name', 'email', 'password')
        _initial = model_to_dict(instance.dragonuser, _fields) \
            if instance is not None else {}
        kwargs['initial'] = _initial
        super(ParentCreationForm, self).__init__(*args, **kwargs)
        self.fields.update(fields_for_model(DragonUser, _fields))

答案 1 :(得分:1)

问题是Python不会让你在调用init时为“实例”指定一个关键字参数(正如在... / django / contrib / admin / options.py:1085中所做的那样)因为由于参数的顺序,调用中的第一个参数被映射到“实例”,然后第三个参数也被映射到“实例”,因为它被指定为关键字参数。

要解决此问题,请从instance=None签名中删除__init__,然后在方法的第一行执行此操作:

instance = kwargs.get("instance")

同时从超级调用中移除instance=instance,因为实例现在应该在kwargs中携带。