BBS阶段性测试总要求
django登录报错
Error: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试。
原因分析:出现这种情况在Windows中很常见,就是端口被占用
解决措施:这时我们只需改一下端口便可以了
登录前端页面(HTML)
这次页面采用的是bookstrip5:Bootstrap 入门 · Bootstrap v5 中文文档 v5.3 | Bootstrap 中文网 (bootcss.com)
html<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
html<style> html, body { height: 100%; } body { display: flex; align-items: center; padding-top: 40px; padding-bottom: 40px; background-color: #f5f5f5; } .form-signin { max-width: 330px; padding: 15px; } .form-, .form-floating:focus-within { z-index: 2; } .form-signin input[type="email"] { margin-bottom: -1px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .form-signin input[type="password"] { margin-bottom: 10px; border-top-left-radius: 0; border-top-right-radius: 0; a { color: rgba(1, 4, 12, 0.92); ext-decoration: none; } } </style>
html# body部分: <body> <main class="form-signin w-100 m-auto"> <div class="text-center"> <div class="form-group"> <label for="id_avatar"> <img class="mb-4 " src="https://tse3-mm.cn.bing.net/th/id/OIP-C.VeJFhbdc95msPtA2RFHHbwAAAA?rs=1&pid=ImgDetMain" alt="" height="80px" width="80px" id="id_img1" style="margin-left: 20px"> </label> <input type="file" id="id_avatar" class="form-control" accept="image/*" style="display: none"> <h1 class="h3 mb-3 fw-normal">糖果爱上我</h1> </label> </div> </div> <form id="login_form"> {% csrf_token %} <div class="form-floating"> <div class="group-group"> <label for="id_username">用户名</label> <input type="text" name="username" class="form-control" id="id_username"> <span class="pull-right error" style="color: red"> </span> </div> <div class="form-group"> <label for="floatingInput">密码</label> <input type="password" name="password" class="form-control" id="id_password"> <span class="pull-right error" style="color: red"> </span> </div> <div class="form-group"> <label for="floatingInput">验证码</label> <div class="row"> <div class="col-md-6"> <input type="text" name="code" class="form-control" id="id_code"> </div> <img src="/get_valid_code/" alt="" class="col-md-6" height="35" id="id_img"> </div> </div> </div> </form> <div class="w-100 btn btn-lg btn-primary" id="id_submit" style="margin-top: 20px">登录</div> <span class="error" style="color: darkred;margin-left: 10px" id="id_error"></span> <p style="color: #888888">您还没账号吗?那我们先注册一个吧~ <a href="/register/">滴滴</a></p> <p class="mt-5 mb-3 text-muted">* 佳祺今天也要加油鸭</p> </main> </body>
验证码功能
能够显示验证码图片,随机改变验证码,点击图片就会自己刷新验证码
视图层后端,自定义验证码,验证码用session进行保存,方便后面验证是否正确:
pythonfrom django.shortcuts import render, HttpResponse, redirect from PIL import Image, ImageDraw, ImageFont from .utills import get_random_code, get_random_rgb from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout import random, json from io import BytesIO def get_valid_code(request): height = 38 width = 300 image_tmp = Image.new('RGB', (300, 38), (255, 255, 255)) # 把空图片放在了画板上,就可以写字了 draw = ImageDraw.Draw(image_tmp) # 加入字体 img_font = ImageFont.truetype('./static/font/ss.TTF', 23) # 验证码 code_str = get_random_code() print(code_str) # 重要,要保存 request.session['code'] = code_str for i, item in enumerate(code_str): draw.text((30 + i * 50, 3), item, fill=get_random_rgb(), font=img_font) # (x轴,y轴),字,字颜色,字体 # 增加难度--->在图片上画点 for i in range(30): draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_rgb()) # 画弧形 x = random.randint(0, width) y = random.randint(0, height) draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_rgb()) # 在图片上划线 for i in range(3): x1 = random.randint(0, width) x2 = random.randint(0, height) y1 = random.randint(0, width) y2 = random.randint(0, height) draw.line((x1, y1, x2, y2), fill=get_random_rgb()) # 放在内存中,一旦不用,自动清理内存 my_io = BytesIO() image_tmp.save(my_io, 'png') return HttpResponse(my_io.getvalue())
讲图片渲染在前端html页面:
html<div class="form-group"> <label for="floatingInput">验证码</label> <div class="row"> <div class="col-md-6"> <input type="text" name="code" class="form-control" id="id_code"> </div> <img src="/get_valid_code/" alt="" class="col-md-6" height="35" id="id_img"> </div> </div>
设置验证码id,设置点击事件,使点击验证码图片会自己刷新验证码:
html<script> $('#id_img').click(function () { // img标签有个特性:只要src变了,就会重新src地址请求拿数据 var url = $(this).attr('src') + '?' // /get_valid_code/??? console.log(url) $(this).attr('src', url) }) </script>
图片渲染在前端配置
在django中,有两个额外自己建立的文件包:
media:一般存入其他用户上传的图片等等
static: 一般用于自身写入的引入样式,图片等等
因此,存入的图片,我们想要渲染在前端页面,也需配置成静态文件
python# settings.py STATIC_URL = '/static/' STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/' # 路由 path('media/<path:path>', serve, {'document_root': settings.MEDIA_ROOT}),
ajax提交登录
前端把用户提交的数据发送到后端,设置button点击事件,用ajax提交数据:
html<script> $('#id_submit').click(function () { var serialize_data = $('#login_form').serializeArray() console.log(serialize_data) var data = {} var username = $('[name="username"]').val() var password = $('[name="password"]').val() var code = $('[name="code"]').val() var csrfmiddlewaretoken = $('[name="csrfmiddlewaretoken"]').val() data['username'] = username data['password'] = password data['code'] = code data['csrfmiddlewaretoken'] = csrfmiddlewaretoken console.log(data) $.ajax({ url: '', method: 'post', data: data, success: function (data) { console.log(data) if (data.code == 100) { location.href = data.url } else { $("#id_error").html(data.msg) } } }) }) </script>
后端拿到前端数据,先对验证码进行对比,然后使用auth模块直接讲用户名和密码与数据库中的进行比较,返回给前端信息,成功便直接跳转到主页面:
pythondef login(request): if request.method == 'GET': return render(request, 'login.html') else: username = request.POST.get('username') password = request.POST.get('password') net_code = request.POST.get('code').lower() # code = request.POST.get('code').lower() # 会存在bug # 1 校验验证码,取出老验证码,忽略大小写 old_code = request.session.get('code').lower() if code == old_code: # 2 去验证用户了---》 user = authenticate(username=username, password=password) if user: # 登录成功--->内部写session了 auth_login(request, user) return JsonResponse({'code': 100, 'msg': '登录成功', 'url': '/'}) else: return JsonResponse({'code': 101, 'msg': '用户名或密码错误'}) else: return JsonResponse({'code': 102, 'msg': '验证码错误'})