<p>我觉得你回答了你自己的问题:)</p>
<p>关于<code>check_password</code>方法的文档如下:
<a href="http://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.models.User.check_password">http://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.models.User.check_password</a></p>
<pre><code>success = user.check_password(request.POST['submitted_password'])
if success:
# do your email changing magic
else:
return http.HttpResponse("Your password is incorrect")
# or more appropriately your template with errors
</code></pre>
<p>由于您已经将request.user传递到表单构造函数中(看起来您已经出于自己的原因重写了<code>__init__</code>),因此您可以毫无困难地将所有逻辑放入表单中。</p>
<pre><code>class MyForm(forms.Form):
# ...
password = forms.CharField(widget=forms.PasswordInput)
def __init__(self, user, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.user = user
def clean_password(self):
valid = self.user.check_password(self.cleaned_data['password'])
if not valid:
raise forms.ValidationError("Password Incorrect")
return valid
</code></pre>
<h2>查看表单后更新</h2>
<p>好的。主要问题是<code>__init__</code>被定义了两次,使得第一条语句无用。我看到的第二个问题是,当我们真的不需要时,我们将对<code>user</code>执行多个查询。</p>
<p>我们有点偏离了你最初的问题,但希望这是一个学习的经验。</p>
<p>我只改变了几件事:</p>
<ul>
<li>删除了额外的<code>__init__</code>定义</li>
<li>将<code>__init__</code>更改为接受<code>User</code>实例而不是文本<code>username</code></li>
<li>因为我们传入了一个用户对象,所以删除了对<code>User.objects.get(username=username)</code>的查询。</li>
</ul>
<p>只需记住传递表单构造函数<code>user=request.user</code>,而不是<code>username=request.user.username</code></p>
<h2></h2>
<pre><code>class EmailChangeForm(forms.Form):
email = forms.EmailField(label='New E-mail', max_length=75)
password = forms.CharField(widget=forms.PasswordInput)
def __init__(self, user=None, *args, **kwargs):
self.user = user
super(EmailChangeForm, self).__init__(*args, **kwargs)
def clean_password(self):
valid = self.user.check_password(self.cleaned_data['password'])
if not valid:
raise forms.ValidationError("Password Incorrect")
def clean_email(self):
email = self.cleaned_data.get('email')
# no need to query a user object if we're passing it in anyways.
user = self.user
# Check if the new email address differs from the current email address.
if user.email == email:
raise forms.ValidationError('New email address cannot be the same \
as your current email address')
return email
</code></pre>
<p>最后,由于我们在这里讨论的是良好的实践,我建议您按照Skirmantas的建议将当前视图代码移动到表单方法中,这样您就可以简单地调用<code>myform.send_confirmation_email</code>。</p>
<p>听起来是个不错的锻炼!</p>