When entering a mobile number, you need to check whether the mobile number has been registered , Then click login to submit the mobile number and verification to the backend , Verify the mobile number and verification code again .
Use here form To render the field to the front end , stay form Medium check field .
First pass the fields into the template :
views.py:
def login_sms(request):
if request.method == 'GET':
form = LoginSmsForm(request.GET)
return render(request, 'user/login_sms.html', dict(form=form))
login.html:
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="account">
<h2 class="text-center"> SMS login </h2>
<form id="form_data">
{% csrf_token %}
{% for field in form %}
{% if field.label == ' Verification Code ' %}
<div class="form-group">
<label for="{
{ field.id_for_label }}">{
{ field.label }}</label>
<div class="row">
<div class="col-xs-6">
{
{ field }}
<span class="error_msg"></span>
</div>
<div class="col-xs-6">
<button id="get_code" type="button" class="btn btn-default"> Click to get the verification code </button>
</div>
</div>
</div>
{% else %}
<div class="form-group">
<label for="{
{ field.id_for_label }}">{
{ field.label }}</label>
{
{ field }}
<span class="error_msg"></span>
</div>
{% endif %}
{% endfor %}
<div>
<button type="button" id="login_sms" class="btn btn-primary"> deng record </button>
<div class="pull-right">
<a href="{% url 'login' %}"> The user login >>></a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
Click to get the verification code , send out ajax request :
// Bind the event of clicking to obtain the verification code
function bindGetCodeEvent(){
$('#get_code').click(function () {
var phoneEle = $('#id_phone');
var phone_numbe = phoneEle.val().trim();
var phone_reg = /^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/
if (phone_numbe && phone_reg.test(phone_numbe)){
phoneEle.next().text('');
// After the verification is passed send out ajax request
$.ajax({
url:'{% url "sms_code" %}',
type:'get',
// tpl: SMS template
data:{phone:phone_numbe, tpl:"login"},
success:function (res){
if (res.status){
// Turn on the countdown effect
SmsTimer();
}else{
phoneEle.next().text(res.error_msg.phone);
}
}
})
}else {
phoneEle.next().text(' The mobile number format is wrong !');
return false
}
})
}
Countdown function :
// Countdown effect function
function SmsTimer() {
// Set the label to non clickable
// jquery The variables of are usually expressed in $ start
var $btnEle = $('#get_code');
$btnEle.prop('disable',true);
// Set the timer reading effect and modify the label text content
var timer = 60;
var t = setInterval(
function () {
$btnEle.text(`${timer} Seconds to resend `);
timer--;
// If it is less than 0 The timer is cleared and $btnEle Set to operable
if (timer <= 0){
clearInterval(t);
$btnEle.text(' Click to get the verification code ');
$btnEle.prop('disable',false);
}
},
1000 // 1 Execute this function once in seconds
)
}
Send login data :
// Send login data
function sendLoginData() {
// Get all the data entered by the user
// Send data to back end
// Perform some page effect processing according to the response results
// Bind click event
$('#login_sms').click(function () {
var data = $('#form_data').serialize(); // Get form All the data in the form
$.ajax({
url: '{% url 'login_sms' %}',
type: 'post',
data: data,
success:function (res) {
if (res.status){
location.href = res.path;
}else{
$.each(res.error_msg,function (k,v){
$('#id_' + k).next().text(v)
})
}
}
})
})
}
Overall data ( cell-phone number 、 Verification Code ) Data verification during submission :
class LoginSmsForm(BootStrapForm, forms.Form):
phone = forms.CharField(label=' cell-phone number ', validators=[mobile_validate, ])
sms_code = forms.CharField(label=' Verification Code ')
def clean_phone(self):
''' Mobile number uniqueness verification '''
phone = self.cleaned_data.get('phone')
phone_require = models.UserInfo.objects.filter(phone=phone)
if not phone_require.exists():
raise ValidationError(' The mobile phone number has not been registered , Please register first !!')
return phone
def clean_sms_code(self):
''' Verification code verification * Take out sms_code、phone * Get the connection , from redis Remove from Verification Code * If it is different, an error is thrown Be careful : Generally, the local hook only gets the current local variable , Unable to get other variables , If in phone Cannot get in email The object of Solution : phone Must be in sms_code Before the verification , The order is fields Specified in the . '''
sms_code = self.cleaned_data.get('sms_code')
phone = self.cleaned_data.get('phone')
conn = get_redis_connection('sms_code')
code = conn.get(phone)
if code is not None:
if code.decode('utf-8') != sms_code.strip():
raise ValidationError(' Verification code error !!!')
else:
raise ValidationError(' The verification code is invalid or has timed out !!')
return code
Data verification when sending verification code :
class SendSmsForm(forms.Form):
phone = forms.CharField(label=' cell-phone number ', validators=[mobile_validate, ])
# rewrite init Method accepts additional parameters (request)
def __init__(self, request, *args, **kwargs):
super().__init__(*args, **kwargs)
self.request = request
def clean_phone(self):
''' Mobile number and SMS template verification '''
tpl = self.request.GET.get('tpl')
try:
sms_template_id = settings.SMS_TEMPLATE_ID[tpl]
except:
raise ValidationError(' SMS template error !!')
phone = self.cleaned_data.get('phone')
unique_phone = models.UserInfo.objects.filter(phone=phone)
# When obtaining the SMS verification code, you need to distinguish between registration and login
if tpl == settings.SMS_TEMPLATE_ID.get('register'):
if unique_phone.exists():
raise ValidationError(' The mobile phone number has been registered !')
elif tpl == settings.SMS_TEMPLATE_ID.get('login'):
if not unique_phone.exists():
raise ValidationError(' The mobile phone number has not been registered !')
elif tpl == settings.SMS_TEMPLATE_ID.get('repassword'):
# TODO Logic TBD
pass
else:
raise ValidationError(f' SMS template :{tpl} non-existent !')
# Send and verify the verification code
# Verify whether the mobile phone number has sent a message , Is it within the validity period
conn = get_redis_connection('sms_code')
if conn.get(phone) is not None:
raise ValidationError(' Text messages have been sent !!')
# Generate verification code
sms_code = '%06d' % random.randint(1, 999999)
# Save the verification code to redis in
conn.set(phone, sms_code, ex=settings.SMS_CODE_EXPIRE)
# Send a text message
obj = MySmsSender()
obj.send(phone, sms_template_id, sms_code)
return phone
complete view Try the function :
Sign in :
def login_sms(request):
if request.method == 'GET':
form = LoginSmsForm(request.GET)
return render(request, 'user/login_sms.html', dict(form=form))
else:
form = LoginSmsForm(data=request.POST)
if form.is_valid():
# TODO Save the data after successful login to session in , Convenient for subsequent use
return JsonResponse(dict(status=True, path=reverse('index')))
else:
return JsonResponse(dict(status=False, error_msg=form.errors))
Send verification code :
def sms_code(request):
''' Get cell phone number , Check cell phone number , Send SMS verification code * format checks * Have you registered '''
form = SendSmsForm(request, data=request.GET)
if form.is_valid():
return JsonResponse({
'status': True})
else:
return JsonResponse({
'status': False, 'error_msg': form.errors})