تغییر پسورد

جنگو

سلام

این حالت برای کاربری است که از قبل وارد سیستم شده و حالا می خواهد پسورد خود را عوض کند. برای این کار به سه فیلد احتیاج است. پسورد قبلی، پسورد جدید و تأیید پسورد جدید.

خوب در گام اول 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

مطلب قبلی: ویوی تکمیل بازیابی پسورد

 

بدون دیدگاه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

جنگو
پیکربندی گواهینامۀ https

سلام حالا می خواهیم برنامۀ خودمان را با گواهینامۀ https امن کنیم. ساده ترین کار برای انجام آن Let’s Encrypt است. قبل از Let’s Encrypt هرگز تنظیمات https به این راحتی نبوده و مهمتر اینکه اینکار کاملاً رایگان است. آن ها راه حلی به نام certbot را ارائه داده اند …

جنگو
پیکربندی سرویس ایمیل

سلام یکی از بهتر سرویس دهنده های ایمیل Mailgun با قابلیت ۱۲ هزار ایمیل رایگان در ماه است. به صورت رایگان ثبت نام کنید. برای اینکار باید آن را با سرویس دهندۀ دامین خود تنظیم کنید که در این آموزش از tamadon.org استفاده شده است. حالا اولین رکورد DNS را …

جنگو
پیکربندی NGINX

سلام کار بعدی که قرار است انجام شود؛ تنظیمان Nginx به شکلی است که پاسخگویی و سرویس دهی مربوط به فایل های استاتیک را خود انجام دهد و سایر درخواست ها را به Gunicorn بفرستد. یک فایل پیکربندی با نام boards را درون /etc/nginx/sites-available/ و با محتوای زیر اضافه می …

هرگونه استفادۀ از این آموزش به صورت رایگان و با ارجاع به تمدن جایز است.