2015-12-30 14 views
0

美好的一天所以!不能將'user'參數傳遞給django中的ChangePasswordForm

我在學習基於類的視圖的Django(1.8)。 Django本身提供了一個可以更改用戶密碼的認證模塊。當使用Django的 PasswordChangeForm(其延伸Django的 SetPasswordForm),I偶然發現以下錯誤:

init() missing 1 required positional argument: 'user'

當我看一看SetPasswordForm類,我可以看到它需要一個用戶對象作爲參數。

def __init__(self, user, *args, **kwargs): 
    self.user = user 
    super(SetPasswordForm, self).__init__(*args, **kwargs) 


我是怎麼開始呢?
首先,在我看來,我只是分配Django的PasswordChangeForm:

class ChangePassword(LoginRequiredMixin, FormView): 
    template_name = 'users/reset_password.html' 
    form_class = PasswordChangeForm 

而導致過程的錯誤,因爲沒有用戶對象已經提供。

那麼我試圖解決這個問題呢?

嘗試之一:從PasswordChangeForm繼承,並增加了INIT方法定製形式。
由於PasswordChangeForm不具有INIT方法,我裝箱稱爲MyPasswordChangeForm一種新形式的類,它從PasswordChangeForm繼承,並增加了在init:

class MyPasswordChangeForm(PasswordChangeForm): 
    def __init__(self, request, *args, **kwargs): 
     super(MyPasswordChangeForm, self).__init__(request.user, *args, **kwargs) 

預期結果:MyPasswordChangeForm->從PasswordChangeForm繼承和添加INIT->超INIT->執行初始化在SetPasswordForm
實際結果:超被調用LoginRequiredMixin:

init() missing 1 required positional argument: 'request'
stack-tr l:80 return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)

嘗試 '二':微小變化 改變超> MyPasswordChangeFrom到超> PasswordChangeForm

嘗試三:使用混入,但不得不相同的結果如上述不幸。

嘗試四:還沒做完,但會是最後的選擇嗎?但是,必須儘可能使用django的表單。

所以我的問題是... 有人可以給我如何通過Django的PasswordChangeForm通(認證)的用戶對象的Django的SetPasswordForm暗示或小的解釋,這樣我就可以使用盡可能多的目前現有的表格可能存在。

在此先感謝!

回答

5

request在初始化時不會默認發送到FormView。你必須以某種方式潛入。

根據您的嘗試#1,做一個很好的方式覆蓋方法get_form_kwargs()FormView,並添加request作爲重點它super已經提供了字典。然後,使用kwargs中的MyPasswordChangeForm__init__得到request

Esentially,你會做這樣的事情:

class ChangePassword(LoginRequiredMixin, FormView): 
    template_name = 'users/reset_password.html' 
    form_class = PasswordChangeForm 

    def get_form_kwargs(self, **kwargs): 
     data = super(ChangePassword, self).get_form_kwargs(**kwargs) 
     data['request'] = self.request 
     return data 

,然後在你的窗體的初始化:

def __init__(self, *args, **kwargs): 
    request = kwargs.pop("request") # it's best you pop request, so that you don't get any complains for a parent that checks what kwargs it gets 
    super(MyPasswordChangeForm, self).__init__(request.user, *args, **kwargs)