200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Django使用图片验证码加邮箱或手机号登录

Django使用图片验证码加邮箱或手机号登录

时间:2019-08-12 13:58:45

相关推荐

Django使用图片验证码加邮箱或手机号登录

实现页面效果

实现思路

使用form渲染数据校验手机号(格式、是否注册)、密码以及验证码

生成图片验证码

'''pillow:是python处理图片的模块,很强大'''import randomfrom PIL import Image, ImageDraw, ImageFontdef picture_code():def get_char():'''通过数字获取ASCII表中的对应字母'''return chr(random.randint(65, 90))def get_color():'''获取随机颜色'''return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))# mode:色系 size:宽高 color:颜色# RGB颜色对照表:/commons?type=3img = Image.new(mode='RGB', size=(120, 50), color=(220, 220, 220))# 创建画笔对象draw = ImageDraw.Draw(img, mode='RGB')# 画点 xy:基于图片的坐标,fill:颜色for i in range(10):draw.point([random.randint(0, 120), random.randint(0, 50)], fill='green')# 画线 xy:(起点坐标,终点坐标),width:粗细for i in range(5):draw.line([random.randint(0, 120), random.randint(0, 50), random.randint(0, 120), random.randint(0, 50)],fill='red')# 画圆或弧线 start and end:角度for i in range(3):x = random.randint(0, 120)y = random.randint(0, 50)x2 = x + 4y2 = y + 4draw.arc([x, y, x2, y2], start=0, end=90, fill='red')# 注意点:.ttf文件路径不能含有中文font = ImageFont.truetype('fonts/domi.ttf', 35)char_list = []for i in range(5):char = get_char()char_list.append(char)height = random.randint(10, 15)draw.text([18 * (i + 1), height], text=char, fill='red', font=font)char_code = ''.join(char_list)return img, char_codeif __name__ == '__main__':img, r = picture_code()# 创建在内存中,这里直接生成在本地,方便自己调式查看with open('code.png', 'wb') as f:img.save(f, format='png') # format:格式print(r)

在页面上展示验证码

首先后端需要先定义一个生成验证码的路由和视图。

path('img_code/', account.img_code, name='img_code'),

def img_code(request):img, char_code = picture_code()# 将图片数据写到内存stream = BytesIO()img.save(stream, format='png')# 将验证码放到session中 也可以放到redis中request.session['image_code'] = char_code# 图片验证码有效期,单位秒request.session.set_expiry(settings.IMAGE_CODE_EXPIRY)return HttpResponse(stream.getvalue())

怎么在前端页面中展示验证码:

<img id="img_code" height="34" width="120" src="{% url "img_code" %}" alt="">

完整页面代码:

<div class="container"><div class="row"><div class="col-md-4 col-md-offset-4"><div class="account"><h2 class="text-center">用户登录</h2><form id="form_data">{% csrf_token %}{% for field in form %}{% if field.label == '验证码' %}<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"><img id="img_code" height="34" width="120" src="{% url "img_code" %}" alt=""></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" class="btn btn-primary">登 录</button><div class="pull-right"><a href="{% url 'login_sms' %}">短信验证码登录>>></a></div></div></form></div></div></div></div>

发送登录数据和点击刷新验证码:

// 发送登录数据function sendLoginData() {// 获取用户输入的所有数据// 将数据发送到后端// 根据响应结果进行一些页面效果处理// 绑定点击事件$('#login').click(function () {var data = $('#form_data').serialize(); //拿到form表单中的所有数据$.ajax({url: '{% url 'login' %}',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)})}}})})}// 点击刷新图片验证码的事件function refreshImageCode() {$('#img_code').click(function () {var oldSrc = $(this).attr('src');$(this).attr('src',oldSrc + '?'); // 问号会重新发送一次请求})}

views.py:

def login(request):if request.method == 'GET':form = LoginForm(request)return render(request, 'user/login.html', dict(form=form))else:form = LoginForm(request, data=request.POST)if form.is_valid():return JsonResponse(dict(status=True, path=reverse('index')))else:return JsonResponse(dict(status=False, error_msg=form.errors))

form校验类:

from django import formsfrom django.core.exceptions import ValidationErrorfrom django.db.models import Qfrom web import modelsfrom web.utils.bootstrap_style import BootStrapFormfrom web.utils.enc import set_md5class LoginForm(BootStrapForm, forms.Form):'''手机号或者邮箱登录'''username = forms.CharField(label='手机号或者邮箱')password = forms.CharField(widget=forms.PasswordInput, label='密码')image_code = forms.CharField(label='验证码')def __init__(self, request, *args, **kwargs):super().__init__(*args, **kwargs)self.request = requestdef clean_password(self):'''密码加密传输'''password = self.cleaned_data.get('password')return set_md5(password)def clean_image_code(self):'''验证图片验证码* 用户输入的和后台保存的要一致'''user_code = self.cleaned_data.get('image_code', '')session_code = self.request.session.get('image_code', '')if not session_code:raise ValidationError('验证码已经过期!!')if user_code.strip().upper() != session_code.upper():raise ValidationError('验证码错误!!!')return session_codedef clean(self):'''手机号邮箱校验'''username = self.cleaned_data.get('username')password = self.cleaned_data.get('password')uname_or_email = models.UserInfo.objects.filter(Q(Q(phone=username)| Q(email=username)),password=password).exists()if not uname_or_email:self.add_error('username','用户名或密码错误!!')return self.cleaned_data

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。