我正在尝试使用自己的模板而不是自定义Django管理auth_view在Django 1.6中实现重置密码,并且我主要遵循了本教程; https://ruddra.com/posts/implementation-of-forgot-reset-password-feature-in-django/。我设法自定义了重置密码页面和为重置密码而发送的电子邮件,但是当我尝试在没有Django管理表单的情况下使用PasswordResetConfirm()类时,重置链接发送到的确认页面为空白(有效) 。简而言之,当单击电子邮件链接以重置密码时,网页为空白,但标题为顶部的确认,因此代码中的某些内容被阻止或丢失。我已经尝试了许多教程,但是没有用。我已经将/ rest / ..更改为URL中的account / reset,它与电子邮件中的链接匹配,并且现在可以用于访问PasswordResetConfirmView(),但是它会呈现错误“ SetPasswordForm”对象没有属性“ set_cookie” ,如何在Django 1.6中解决此问题?我还注意到,我无法在Django 1.6中导入许多教程使用的update_session_auth_hash,它似乎存在于Django 1.7及更高版本中。相反,在本教程中,我尝试使用密码哈希器PBKDF2PasswordHasher和SHA1PasswordHasher。 https://apimirror.com/django~1.9/topics/auth/passwords,但不确定是否与SetPasswordForm中有关set_cookies的属性错误有关。
我尝试通过在应用程序之后的“设置”中的INSTALLED_APPS中将“ django.contrib.admin”放置在“设置”中,从而将用于在确认步骤中更改密码的自定义Django管理表单“拔出”到空白页面,并在文本顶部显示确认。 。我还更改了模板password_reset_confirm.html
In views.py, following from linked tutorial
class PasswordResetConfirmView(FormView):
template_name = "registration/password_reset_confirm.html"
success_url = 'registration/password_reset_complete.html'
form_class = SetPasswordForm
def post(self, request, uidb64=None, token=None, *arg, **kwargs):
"""
View that checks the hash in a password reset link and presents a
form for entering a new password.
"""
UserModel = get_user_model()
form = self.form_class(request.POST)
assert uidb64 is not None and token is not None # checked by URLconf
try:
uid = urlsafe_base64_decode(uidb64)
user = UserModel._default_manager.get(pk=uid)
except (TypeError, ValueError, OverflowError,UserModel.DoesNotExist):
user = None
if user is not None and default_token_generator.check_token(user,
token):
if form.is_valid():
new_password= form.cleaned_data['new_password2']
user.set_password(new_password)
user.save()
messages.success(request, 'Password has been reset.')
return self.form_valid(form)
else:
messages.error(request, 'Password reset has not been
unsuccessful.')
return self.form_invalid(form)
else:
messages.error(request,'The reset password link is no longevalid.')
return self.form_invalid(form)```
In urls.py
url(r'^account/password_reset/', ResetPasswordRequestView.as_view(),
name="reset_password"),
url(r'^account/password/reset/done/', ResetPasswordRequestView.as_view(),
name="reset_password_done"),
url(r'^reset/(?P<uidb64>[0-9A-Za-z]+)/(?P<token>.+)/$',
PasswordResetConfirmView.as_view(),name='password_reset_confirm'),
# changed url to
url(r'^account/reset/(?P<uidb64>[0-9A-Za-z]+)/(?P<token>.+)/$',
PasswordResetConfirmView.as_view(),name='password_reset_confirm'),
# which matches email link
{{ protocol }}://{{ domain }}/account/reset/{{ uid }}/{{ token }}/
In password_reset_confirm.html in the Registration folder
{% extends 'base.html' %}
{% block title %}Enter new password{% endblock %}
{% block content %}
<h1>Set a new password!</h1>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Change my password">
</form>
{% endblock %}
# in forms.py from tutorial, works in the tutorial example but yields
# an Attribute error that the form doesn't have set_cookies
# after disconnecting from Djando Admin confirmation forms used in the
#tutorial
class SetPasswordForm(forms.Form):
# """
#
#A form that lets a user change set their password without entering the old
# password
# """
error_messages = {
'password_mismatch': ("The two password fields didn't match."),
}
new_password1 = forms.CharField(label=("New password"),
widget=forms.PasswordInput)
new_password2 = forms.CharField(label=("New password confirmation"),
widget=forms.PasswordInput)
def clean_new_password2(self):
password1 = self.cleaned_data.get('new_password1')
password2 = self.cleaned_data.get('new_password2')
if password1 and password2:
if password1 != password2:
raise forms.ValidationError(
self.error_messages['password_mismatch'],
code='password_mismatch',
)
return password2
答案 0 :(得分:1)
我已经设法解决了我的问题。如果有人遇到相同的问题,我将执行以下操作;
本教程示例正常工作,但是即使删除了模板password_reset_confirm.py中的所有与Django管理(admin)相关的标签后,仍然显示了admin视图(即使在运行manage.py syncdb并抛出并启动新的sql-db之后) ,因此我在Registration文件夹中使用了一个名为test_reset_confirm.html的新模板,其中包含原始password_reset_confirm.py中与表单相关的代码部分(中间部分),并通过添加enctype = multipart / form-data来填写表单信息; 和密码字段中的信息 按照本教程的示例9,在views.py中,我将PasswordResetConfirmView从类更改为函数。 https://www.programcreek.com/python/example/54414/django.contrib.auth.forms.SetPasswordForm;
def PasswordResetConfirmView(request, uidb64=None, token=None,
token_generator=default_token_generator,
post_reset_redirect=None,current_app=None):
"""
View that checks the hash in a password reset link and presents a
form for entering a new password.
"""
UserModel = get_user_model()
form = SetPasswordForm(request.POST)
template_name='registration/test_reset_confirm.html'
assert uidb64 is not None and token is not None # checked by URLconf
try:
uid = urlsafe_base64_decode(uidb64)
user = UserModel._default_manager.get(pk=uid)
except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
user = None
if user is not None and token_generator.check_token(user, token):
validlink = True
if request.method == 'POST':
form = SetPasswordForm(request.POST)
if form.is_valid():
print request.POST,'request.POST'
print form.cleaned_data,'form.cleaned_data'
new_password= form.cleaned_data['new_password2']
user.set_password(new_password)
user.save()
#form.save()
messages.add_message(request, messages.SUCCESS, 'Your password has now been changed and you can login on any system site!',fail_silently=True)
return HttpResponseRedirect(post_reset_redirect)
else:
form = SetPasswordForm()
c = {"form":form}
c.update(csrf(request))
return TemplateResponse(request, template_name, c,
current_app=current_app)
# Setpasswordform in forms.py
class SetPasswordForm(forms.Form):
new_password1 = forms.CharField(widget=forms.PasswordInput)
new_password2 = forms.CharField(widget=forms.PasswordInput)
error_messages = {
'password_mismatch': ("The two password fields didn't match."),
}
class Meta:
model = User
fields = ('password',)
def __init__(self,*args, **kwargs):
super(SetPasswordForm, self).__init__(*args, **kwargs)
def clean(self):
cleaned_data = super(SetPasswordForm, self).clean()
return cleaned_data