Как настроить форму подтверждения Django и просмотреть в запросе пароля - PullRequest
1 голос
/ 19 мая 2019

Я пытаюсь реализовать сброс пароля в Django 1.6 с моими собственными шаблонами вместо пользовательского администрирования Django auth_view, и я в основном следовал этому руководству; https://ruddra.com/posts/implementation-of-forgot-reset-password-feature-in-django/. Мне удалось настроить страницу сброса пароляи электронное письмо, отправленное для сброса пароля, но страница подтверждения, на которую отправляется ссылка для сброса, пуста, когда я пытаюсь использовать класс PasswordResetConfirm () без форм администрирования Django (которые работают).Короче говоря, при нажатии на ссылку электронной почты для сброса пароля веб-страница остается пустой, но в верхней части она называется «Подтверждение», поэтому что-то в коде блокируется или отсутствует.Я пробовал множество уроков, но ничего не работает.Я изменил / rest / .. на account / reset в URL, который соответствует ссылке в электронном письме и теперь работает для получения доступа к PasswordResetConfirmView (), но он отображает ошибку «SetPasswordForm» объект не имеет атрибута «set_cookie»Как я могу это исправить в Django 1.6 ?.Я также заметил, что не могу импортировать update_session_auth_hash, который используют многие учебники, в Django 1.6 и, кажется, существует в Django 1.7 и более поздних версиях.Вместо этого я пытаюсь использовать хеши паролей PBKDF2PasswordHasher, SHA1PasswordHasher в этом уроке;https://apimirror.com/django~1.9/topics/auth/passwords но я не уверен, связано ли это с ошибкой атрибута set_cookies в SetPasswordForm.

Я пытался поместить django.contrib.admin в INSTALLED_APPS в Настройках после приложений, что «отключает» пользовательскую форму администрирования 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

1 Ответ

1 голос
/ 22 мая 2019

Мне удалось решить проблему в моем вопросе. Если кто-то сталкивается с той же проблемой, я сделал следующее:

Пример учебника сработал, но представление администратора появилось даже после удаления всех связанных с администрацией Django тегов (admin) в шаблоне password_reset_confirm.py (даже после запуска manage.py syncdb, добавления и запуска нового sql-db) , поэтому я использовал новый шаблон с именем test_reset_confirm.html в папке «Регистрация» с частью кода, связанной с формой (средняя часть) из оригинального password_reset_confirm.py, и заполнил информацию формы, добавив enctype = multipart / form-data; и информация в поле пароля В views.py я изменил PasswordResetConfirmView из класса в функцию, следуя Примеру 9 в этом уроке; 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...