【问题标题】:Django ModelForm Inheritance with request.user results in TypeError on __init__带有 request.user 的 Django ModelForm 继承导致 __init__ 上的 TypeError
【发布时间】:2014-07-30 08:25:54
【问题描述】:

尝试继承 ModelForm 以创建 BaseForm 以更新模型中的 created_bymodified_by 字段。 我的BaseForm

class BaseForm(ModelForm):

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('request', None).user
        super(BaseForm, self).__init__(*args, **kwargs)

    def save(self, *args, **kwargs):
        kwargs['commit']=False
        obj = super(BaseForm, self).save(*args, **kwargs)
        if self.user:
            obj.modified_by = self.user.username            
        obj.save()
        return obj

子窗体为

class InviteForm(BaseForm):

    class Meta:
        model = UserInvitation

我正在通过视图以子形式传递请求

form = InviteForm(instance=instance,request=request)

但它给出了错误

TypeError at /accounts/invitation/
__init__() got an unexpected keyword argument 'request'

如果我不继承BaseForm 并以子形式编写代码,即InviteForm,则错误不存在。

请指出我做错了什么,我不想在每个表单中重复代码。

Traceback:
File "c:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
115.                         response = callback(request, *callback_args, **callback_kwargs)
File "c:\Python27\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
25.                 return view_func(request, *args, **kwargs)
File "C:\Python27\Lib\site-packages\django\bin\mysite\userplus\views.py" in invitation
87.         form = InviteForm(instance=instance,request=request)

Exception Type: TypeError at /accounts/invitation/
Exception Value: __init__() got an unexpected keyword argument 'request'

【问题讨论】:

  • 你能试试def __init__(self, request=None, *args, **kwargs): if request: self.user = request.user吗?
  • 你能发布完整的回溯吗?
  • 您可以尝试简单地将 kwargs 密钥从 request 更改为 req 吗?可能与这个code.djangoproject.com/ticket/20744有关
  • 不,它没有帮助,如果您看到回溯,则错误来自视图 87。form = InviteForm(instance=instance,request=request) 并且仅在继承 ModelForm 时才会影响

标签: django inheritance modelform


【解决方案1】:

要更新您在 UserInvitation 模型中的 modified_by 字段,您应该将其排除在表单中:

class BaseForm(ModelForm):

...

class InviteForm(BaseForm):

    class Meta:
        model = UserInvitation
        exclude = ('modified_by',)

那么在你看来

form = InviteForm(request.POST, instance=instance)
if form.is_valid():
    invite = form.save(commit=false)
    invite.modified_by = request.user
    invite.save()

这样就使用了发出请求的用户。

或者,您可以预先设置用户:

# views.py
instance = Invite(modified_by=request.user)
form = InviteForm(request.POST, instance=instance)
...

【讨论】:

  • “试试”?这个答案出现在低质量队列中。您应该改进它以添加更多实质性信息。现在看起来像是一条评论。
  • 嗨,Tom,这样可以工作,但是当我将此代码移动到 BaseForm 并继承 BaseForm 时,它会中断。
  • 它给出了什么错误,你到底移动了什么?
  • 我正在尝试以 DRY 的方式实现它,我所有的模型都有这些字段(modified_by、created_by)并且希望在后台而不是主窗体中更新它。因此继承。想要在 BaseForm 中而不是在 InviteForm 中保留代码 modified_by=request.user
  • 当您创建传递给表单的实例时,您可以在传入之前设置modified_by,即:instance = Invite(modified_by=request.user) 然后执行form = InviteForm(request.POST, instance=instance),这应该设置它而不必进一步改变任何东西
猜你喜欢
  • 1970-01-01
  • 2018-02-09
  • 2013-06-04
  • 1970-01-01
  • 1970-01-01
  • 2016-03-20
  • 2015-10-16
  • 2018-07-18
相关资源
最近更新 更多