تغییر پسورد
سلام
این حالت برای کاربری است که از قبل وارد سیستم شده و حالا می خواهد پسورد خود را عوض کند. برای این کار به سه فیلد احتیاج است. پسورد قبلی، پسورد جدید و تأیید پسورد جدید.
خوب در گام اول URL را اضافه می کنیم.
myproject/urls.py
url(r'^settings/password/$', auth_views.PasswordChangeView.as_view(template_name='password_change.html'), name='password_change'), url(r'^settings/password/done/$', auth_views.PasswordChangeDoneView.as_view(template_name='password_change_done.html'), name='password_change_done'),
این فرم ها فقط برای کاربرانی کار می کند که به سیستم وارد شده باشند. استفاده از این ویوها فقط برای login_required@ امکان پذیر است. اگر کاربری به سیستم وارد نشده باشد و بخواهد وارد این صفحه شود؛ جنگو او را به صفحۀ ورود یا همان لاگین انتقال می دهد.
پس باید آدرس صفحۀ لاگین را به جنگو معرفی کنیم.
myproject/settings.py
LOGIN_URL = 'login'
قالب مربوط به صفحۀ تغییر پسورد را ایجاد می کنم.
templates/password_change.html
{% extends 'base.html' %} {% block title %}Change password{% endblock %} {% block breadcrumb %} <li class="breadcrumb-item active">Change password</li> {% endblock %} {% block content %} <div class="row"> <div class="col-lg-6 col-md-8 col-sm-10"> <form method="post" novalidate> {% csrf_token %} {% include 'includes/form.html' %} <button type="submit" class="btn btn-success">Change password</button> </form> </div> </div> {% endblock %}
یک نکته ای را تکرار کنم. در صفحۀ قالب هیچ کد یا فیلدی وجود ندارد که مربوط به تغییر پسورد باشد اما بعد از ایجاد چند تگ مربوط به طراحی می بینیم که فیلدها به درستی در صفحه ایجاد شده اند. علت آن ساده است. اگر دقت شود در فایل مربوط به URL ما به جنگو گفته ایم که:
auth_views.PasswordChangeView.as_view(template_name='password_change.html')
این یعنی اینکه ویوی پیش فرض تغییر پسورد در جنگو را به آدرس قالب password_change.html بفرست.
و حالا هم تأیید تغییر پسورد و قالب آن
templates/password_change_done.html
{% extends 'base.html' %} {% block title %}Change password successful{% endblock %} {% block breadcrumb %} <li class="breadcrumb-item"><a href="{% url 'password_change' %}">Change password</a></li> <li class="breadcrumb-item active">Success</li> {% endblock %} {% block content %} <div class="alert alert-success" role="alert"> <strong>Success!</strong> Your password has been changed! </div> <a href="{% url 'home' %}" class="btn btn-secondary">Return to home page</a> {% endblock %}
حالا می خواهیم فایل تستی را برای نمونههای آزمایشی ایجاد کنیم. یک فایل جدید به نام test_view_password_change.py می سازیم.
به دلیل اینکه نمونه های تستی خیلی طولانی است در این قسمت ذکر نشده است و برای مشاهدۀ آن می توانید روی لینک کلیک کنید.
accounts/tests/test_view_password_change.py (مشاهده کد کامل)
class LoginRequiredPasswordChangeTests(TestCase): def test_redirection(self): url = reverse('password_change') login_url = reverse('login') response = self.client.get(url) self.assertRedirects(response, f'{login_url}?next={url}')
صفحۀ بالا با این سناریو ساخته شده است که کاربر هنوز وارد سیستم نشده و قصد ورود به صفحۀ تغییر پسورد را دارد و به همین دلیل به صفحۀ لاگین ریدایرکت می شود.
accounts/tests/test_view_password_change.py (مشاهده کد کامل)
class PasswordChangeTestCase(TestCase): def setUp(self, data={}): self.user = User.objects.create_user(username='john', email='john@doe.com', password='old_password') self.url = reverse('password_change') self.client.login(username='john', password='old_password') self.response = self.client.post(self.url, data)
کلاس PasswordChangeTestCase یک کاربر جدید را به صورت موقت ایجاد میکند و یک درخواست POST به ویوی password_change ارسال می کند. در ادامه قرار است به جای استفاده از کلاس TestCase از این کلاس استفاده کنیم.
accounts/tests/test_view_password_change.py (مشاهده کد کامل)
class SuccessfulPasswordChangeTests(PasswordChangeTestCase): def setUp(self): super().setUp({ 'old_password': 'old_password', 'new_password1': 'new_password', 'new_password2': 'new_password', }) def test_redirection(self): ''' A valid form submission should redirect the user ''' self.assertRedirects(self.response, reverse('password_change_done')) def test_password_changed(self): ''' refresh the user instance from database to get the new password hash updated by the change password view. ''' self.user.refresh_from_db() self.assertTrue(self.user.check_password('new_password')) def test_user_authentication(self): ''' Create a new request to an arbitrary page. The resulting response should now have an `user` to its context, after a successful sign up. ''' response = self.client.get(reverse('home')) user = response.context.get('user') self.assertTrue(user.is_authenticated) class InvalidPasswordChangeTests(PasswordChangeTestCase): def test_status_code(self): ''' An invalid form submission should return to the same page ''' self.assertEquals(self.response.status_code, 200) def test_form_errors(self): form = self.response.context.get('form') self.assertTrue(form.errors) def test_didnt_change_password(self): ''' refresh the user instance from the database to make sure we have the latest data. ''' self.user.refresh_from_db() self.assertTrue(self.user.check_password('old_password'))
با استفاده از تابع ()refresh_from_db مطمئن می شویم که آخرین وضعیت دیتا را استفاده می کنیم. این تابع، جنگو را مجبور می کند تا درخواست جدیدی را به دیتابیس ارسال و داده ها را به روز کند. مجبوریم از این تابع استفاده کنیم چراکه قرار است change_password پسوردها را در دیتابیس تغییر دهد و بنابراین برای اینکه مطمئن شویم پسورد عوض شده چاره ای نداریم جز آنکه به دیتا بیس وصل شویم، آخرین داده ها را بررسی کنیم و آن را با پسورد جدید خود مقایسه کنیم.
و در پایان آدرس کدهای مربوط به بخش اعتبارسنجی:
http://tamadon.net/python/code/493-django-beginners-guide-part5.zip
ترجمۀ اختصاصی توسط تمدن
مطلب بعدی:فصل بعدی: مقدمه و مفهوم ORM
مطلب قبلی: ویوی تکمیل بازیابی پسورد
دیدگاه خود را ثبت کنید
تمایل دارید در گفتگو شرکت کنید؟نظری بدهید!