1.login功能:
前端用Django的form表单来写的:
from django import forms from django.core.exceptions import ValidationError # Django内置的正则 from django.core.validators import RegexValidator from blog import models class LoginForm(forms.Form): username = forms.CharField( label="用户名", min_length=3, max_length=12, error_messages={ "required": "用户名不能为空", "min_length": "用户名最少3位", "max_length": "用户名最长12位" }, widget=forms.widgets.TextInput( attrs={"class": "form-control c1"} ) ) password = forms.CharField( label="密码", min_length=4, max_length=12, error_messages={ "required": "密码不能为空", "min_length": "密码最短4位", "max_length": "密码最长12位" }, widget=forms.widgets.PasswordInput( attrs={"class": "form-control"} ) )
login.html
<form autocomplete="off" novalidate> {# {% csrf_token %}#} <div class="form-group"> <label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label> {{ form_obj.username }} </div> <div class="form-group"> <label for="{{ form_obj.password.id_for_label }}">{{ form_obj.password.label }}</label> {{ form_obj.password }} </div> <div class="form-group" id="v-code-wrapper"> <label for="{{ form_obj.password.id_for_label }}">验证码</label> <input type="text" class="form-control" id="v-code-input"> <img src="/v_code/" alt="" id="v-code" > </div> <button type="button" class="btn btn-success" id="login-button">登录</button> <span class="error" id="login-error"></span> </form>
views:一个login,一个v_code
def login(request): # 生成forms组件对象 form_obj = forms.LoginForm() # 如果是post请求 if request.method == 'POST': # 返回成功 code: 0 ret = {'code': 0} # 获取用户名 username = request.POST.get("username") # 获取密码 password = request.POST.get("password") # 获取验证码 v_code = request.POST.get("v_code", "") # 判断用户输入的验证码是否与session里面存的v_code一样 if v_code.upper() == request.session.get("v_code", ""): # 用Django的 auth用户验证装饰器去查看用户名和密码是否正确 user = auth.authenticate(username=username, password=password) # 正确发送index页面到前端 if user: ret['data'] = '/index/' # 不正确就把code改为1 然后 添加data错误信息 else: ret['code'] = 1 ret['data'] = "用户名或密码错误" # 验证码校验不正确的话返回code 1,data错误信息 else: ret['code'] = 1 ret['data'] = "验证码错误!" # 通过JsonResponse把ret json格式的数据发回去 return JsonResponse(ret) # 返回render form_obj数据给login.html页面 return render(request, "login.html", {"form_obj": form_obj}) # 图片随机数字验证码 @never_cache def v_code(request): # pillow模块 from PIL import Image, ImageDraw, ImageFont import random # 生成一个随机颜色的内置函数 def get_color(): return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255) # 生成一个图片对象 img_obj = Image.new( # 安全色取色 "RGB", # 图片的长宽 (250, 35), # 图片的颜色 color=get_color() ) # 图片中加文字,生成一个笔画对象 draw_obj = ImageDraw.Draw(img_obj) # 生成一个字体对象,导入一个字体文件(字体文件路径和字体大小) font_obj = ImageFont.truetype("static/font/kumo.ttf", size=28) # 生成一个5个随机英文或数字的组合 tmp_list = [] for i in range(5): num = str(random.randint(0, 9)) low = chr(random.randint(97, 122)) upr = chr(random.randint(65, 90)) # 从上面三个随机取一个 all = random.choice([num, low, upr]) tmp_list.append(all) # 用笔画对象开始画内容 draw_obj.text( # 位置 (i*48+20, 0), # 内容 all, # 颜色 get_color(), # 字体 font=font_obj ) # 把列表里面的5个随机数拼接,得到5个随机生成的字符 v_code_str = "".join(tmp_list) # 把随机字符转成大写当作session参数 request.session['v_code'] = v_code_str.upper() # 直接将图片在内存中保存 from io import BytesIO tmp = BytesIO() # BytesIO()当作句柄 img_obj.save(tmp, "png") # 从内存中保存取到图片数据 data = tmp.getvalue() # 通过content_type控制类型 return HttpResponse(data, content_type="image/png")
Ajax:数据交互
<script> $(document).ready(function () { // 文档加载完之后自动执行的 $("#login-button").click(function () { // 登录按钮点击之后要做的事儿 $.ajax({ url: "/login/", type: "POST", data: { username: $("#id_username").val(), password: $("#id_password").val(), v_code: $("#v-code-input").val() }, success: function (data) { if (!data.code) { location.href = data.data; } else { // 有错误 $("#login-error").text(data.data); } }, error: function (err) { console.log(err) } }) }); // 当form中的input标签获取光标之后,就清空之前的错误信息 $("form input").focus(function () { $("#login-error").text(""); }); // 点击图片刷新验证码 $("#v-code").click(function () { this.src += "?"; }); }) </script>
登录功能----验证码-----然后验证成功-----跳转到主页!