ارسال لینک بازیابی رمز عبور با پیامک در جنگو
سلام این اولین مطلبی هست که توی ویرگول منتشر میکنم . ممنون میشم برای بهتر شدن مطالب بعدی نظراتتو بگین !
اولین کاری که باید بعد اینکه یه پروژه جنگو ساختین اینه که یه اپ با دستور زیر بسازی
python manage.py startapp users
و اون رو توی فایل setting.py اضافه میکنیم
در مرحله بعد باید فیلد شماره تلفن رو به مدل من توی این مثال از کلاس AbstractBaseUser استفاده کردم. در مرحله اول میاییم یه فایل manager.py رو توی اپ users میسازیم. و این کد رو بهش اضافه میکنیم.
from django.contrib.auth.base_user import BaseUserManager
class CustomUserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, phone_number, password, **extra_fields):
"""
Create and save a user with the given phone number and password.
"""
if not phone_number:
raise ValueError('The given phone number must be set')
user = self.model(phone_number=phone_number, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, phone_number, password=None, **extra_fields):
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(phone_number, password, **extra_fields)
def create_superuser(self, phone_number, password=None, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(phone_number, password, **extra_fields)
حالا میاییم توی فایل models.py مدل User خودمون رو تعریف می کنیم. برای اینکار فایل مورد نظر رو به این شکل تغییر میدیم.
from django.db import models
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.base_user import AbstractBaseUser
from django.utils.translation import gettext_lazy as _
from django.core.validators import RegexValidator
from django.utils import timezone
from .manager import CustomUserManager
class CustomUser(AbstractBaseUser, PermissionsMixin):
phone_number = models.CharField(
_('شماره موبایل'),
max_length=11,
unique=True,
validators=[RegexValidator(regex=r'09(\d{9})$')])
phone_number_verified = models.BooleanField(default=False)
is_staff = models.BooleanField(
_('staff status'),
default=False,
)
is_active = models.BooleanField(
_('active'),
default=True,
)
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
objects = CustomUserManager()
USERNAME_FIELD = 'phone_number'
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
جنگو برای بازیابی رمز عبور راهکاری اندیشیده که با ایمیل کار میکنه شما ایمیل رو وارد میکنین لینک به ایمیل شما فرستاده میشه و روی لینک که کلیک کنید میتونین رمز جدید رو بزارین ما میخواییم این کار رو با شماره موبایل انجام بدیم پس فقط لازمه قسمت اول رو بازنویسی کنیم اولین کاری که انجام میدیم اینه که فرم خودمون روی توی فایل forms.py اضافه کنیم. این کد رو به این فایل اضافه میکنیم.
from django import forms
from django.contrib.auth import get_user_model
from django.core.validators import RegexValidator
from django.contrib.auth.tokens import default_token_generator
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.contrib.sites.shortcuts import get_current_site
from django.urls import reverse
from django.conf import settings
import kavenegar
UserModel = get_user_model()
class PasswordResetForm(forms.Form):
phone_number = forms.CharField(label='شماره موبایل', max_length=11,
validators=[RegexValidator(regex=r'09(\d{9})$')])
def send_sms(self, phone_number, reset_link):
try:
api = kavenegar.KavenegarAPI(settings.KAVENEGAR_APIKEY)
message = f'برای بازیابی رمز عبور روی لینک زیر کلیک کنید \n {reset_link}'
params = {
'sender': '1000596446',
'receptor': phone_number,
'message': message,
}
response = api.sms_send(params)
print(response)
except kavenegar.APIException as e:
print(e)
except kavenegar.HTTPException as e:
print(e)
def get_users(self, phone_number):
return UserModel.objects.get(phone_number=phone_number)
def save(self, domain_override=None,
use_https=False, token_generator=default_token_generator,
request=None):
"""
Generate a one-use only link for resetting password and send it to the
user.
"""
phone_number = self.cleaned_data["phone_number"]
if not domain_override:
current_site = get_current_site(request)
site_name = current_site.name
domain = current_site.domain
else:
site_name = domain = domain_override
user = self.get_users(phone_number)
user_phone_number = user.phone_number
protocol = 'https' if use_https else 'http'
uid = urlsafe_base64_encode(force_bytes(user.pk))
token = token_generator.make_token(user)
reset_link = protocol + '://' + domain + reverse('password_reset_confirm',
args=[uid, token])
print(reset_link)
self.send_sms(user_phone_number, reset_link)
توی این مثال ما اومدیم برای ارسال پیامک از سرویس کاوه نگار استفاده کردیم در ضمن برای استفاده از کد باید APIKEY که از کاوه نگار میگیرین رو به صورت یه متغییر توی فایل settings.py اضافه کنین به این شکل
KAVENEGAR_APIKEY = 'YOUR_APIKEY'
الان وقتشه بریم سراغ نوشتن view برای این کار توی فایل view.py این کد رو اضافه میکنیم
from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth import get_user_model
from django.contrib.auth.views import PasswordContextMixin
from django.views.generic import FormView
from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator
from django.utils.translation import gettext_lazy as _
from django.urls import reverse_lazy
from .forms import PasswordResetForm
UserModel = get_user_model()
class PasswordResetView(PasswordContextMixin, FormView):
form_class = PasswordResetForm
success_url = reverse_lazy('password_reset_done')
template_name = 'registration/password_reset_form.html'
token_generator = default_token_generator
title = _('Password reset')
@method_decorator(csrf_protect)
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
def form_valid(self, form):
phone_number = form.cleaned_data['phone_number']
try:
user = UserModel.objects.get(phone_number=phone_number)
opts = {
'use_https': self.request.is_secure(),
'token_generator': self.token_generator,
'request': self.request,
}
form.save(**opts)
except UserModel.DoesNotExist:
form.add_error(None, 'این شماره موبایل پیدا نشد!')
return self.form_invalid(form)
return super().form_valid(form)
و در آخر میاییم فایل توی اپ یوزرمون فایل urls.py رو میسازیم و url هایی که نیاز داریم رو توش تعریف می کنیم!
from django.urls import path
from django.contrib.auth import views
from .views import PasswordResetView
urlpatterns = [
path('password_reset/', PasswordResetView.as_view(), name='password_reset'),
path('password_reset/done/', views.PasswordResetDoneView.as_view(), name='password_reset_done'),
path('reset/<uidb64>/<token>/', views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
path('reset/done/', views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]
ما توی این آموزش اومدیم فقط یه ویوو رو تغییر دادیم برای بقیه از همون مدل پیش فرض جنگو استفاده کردیم.
و در آخر اینکه فراموش نکنین این فایل urls رو توی urls اصلی پروژتون اضافه کنید.
ممنون از توجهتون.
مطلبی دیگر از این انتشارات
برگه تقلب کد تمیز | Clean Code Cheat Sheet
مطلبی دیگر از این انتشارات
راهنمای گام به گام حرفه ای شدن، البته در برنامه نویسی!
مطلبی دیگر از این انتشارات
پنج کار برای متوقف کردن احساس سوخت شدن در دور کاری