django框架前后端混合项目之注册、登录功能及页面搭建、图片验证码等相关内容-78

0 头像的上传

# models.py中不需要动
avatar = models.FileField(upload_to='avatar/', default='avatar/default.png')
# setting中配置
MEDIA_ROOT=os.path.join(BASE_DIR,'media')
# 由于FileField会自动保存文件,所以默认以MEDIA_ROOT开始往下找,如果没有配,默认以根路径开始
# 以后上传的文件,都是从media路径往下找

 

1 注册功能错误渲染

    $("#id_submit").click(function () {
       var formdata = new FormData()
       formdata.append('avatar', $('#id_myfile')[0].files[0])
       //第一种方式:
       /*
       formdata.append('username', $('#id_name').val())
       formdata.append('password', $('#id_password').val())
       formdata.append('re_password', $('#id_re_password').val())
       formdata.append('email', $('#id_email').val())
        */
       //第二种方式:
       var ser = $('#form').serializeArray()
       //[{name:name,value:lqz}, {name:password],value:123}, {name:re_password],value:123}, {name:email],value:123@qq.com}]
       //console.log(ser)

       $.each(ser, function (k, v) {
           //console.log(v.name)
           //console.log(v.value)
           formdata.append(v.name, v.value)
      })

       $.ajax({
           url: '/register/',
           method: 'post',
           processData: false,
           contentType: false,
           data: formdata,
           success: function (data) {
               if (data.code == 100) {
                   console.log(data.msg)
                   //js控制的跳转
                   location.href = data.url
              } else {
                   //有错误,需要渲染页面
                   $.each(data.error, function (k, v) {
                       if (k == '__all__') {
                           $(".error").html(v)
                      }
                       $("#id_" + k).next().html(v[0]).parent().addClass('has-error')

                  })

                   //过三(3000毫秒)秒钟,错误信息清除,在匿名函数中执行
                   setTimeout(function () {
                       $('.text-danger').html("").parent().removeClass('has-error')
                  }, 3000)
              }
          }

      })


  })

 

2 用户名变化校验

视图函数

def check_username(request):
   print('xxx')
   res = {'code': 101, 'msg': '该用户已经存在了小兄弟'}
   username = request.GET.get('username')
   user = models.UserInfo.objects.filter(username=username).count()
   if not user:
       res['code'] = 100
       res['msg'] = '不存在'
   return JsonResponse(res)

js代码

// 当光标不再username控件上就发送ajax请求,去后台查询
$('#id_username').blur(function () {
   //this 原生空间,使用它$(),它才变成jq,使用jq的方法
   //alert($(this).val())
   //alert($('#id_username').val())

   $.ajax({
       url: '/check_username/?username=' + $(this).val(),
       method: 'get',
       success: (data) => {
           if (data.code !== 100) {
               $(this).next().html(data.msg).parent().addClass('has-error')
          }
      }
       /*
      success: function (data) {

          if(data.code !==100){
              $('#id_username').next().html(data.msg).parent().addClass('has-error')
          }
          }
        */

  })


})

3 登陆页面搭建

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
   <script src="/static/jquery-3.3.1/jquery-3.3.1.min.js"></script>
   <title>登录</title>
</head>
<body>
<div class="container-fluid">
   <div class="row">
       <h1 class="text-center">登录功能</h1>
       <div class="col-md-6 col-md-offset-3">

           <form id="form">
              {% csrf_token %}

               <div class="form-group">
                   <label for="">用户名</label>
                   <input type="text" name="username" class="form-control">
               </div>
               <div class="form-group">
                   <label for="">密码</label>
                   <input type="password" name="password" class="form-control">
               </div>
               <div class="form-group">
                   <label for="">验证码</label>
                   <div class="row">
                       <div class="col-md-6">
                           <input type="text" name="valid_code" class="form-control">
                       </div>
                       <div class="col-md-6">
                           <img src="/static/img/default.png" height="30" width="450">
                       </div>
                   </div>
                   
               </div>

               <div class="text-center">
                   <input type="button" value="登录" id="id_submit" class="btn btn-danger"><span
                       class="error text-danger" style="margin-left: 10px"></span>
               </div>
           </form>
       </div>
   </div>
</div>
</body>
</html>

4 图片验证码

自定义图片验证码

 

def get_valid(request):
   # 方式一,直接返回一张图片
   # with open('./lhf.jpg','rb') as f:
   #     data=f.read()
   # return HttpResponse(data)

   # 方式二:自己生成一张图片,返回
   # pillow模块:图片处理模块,pip3 install pillow

   # 生成一张图片(Image模块下的new函数,返回一个Image对象)
   # img = Image.new('RGB', (450, 30), (123, 123, 255))
   # # 图片保存(写到硬盘)
   # with open('a.png', 'wb') as f:
   #     img.save(f)
   # # 打开图片
   # with open('./a.png', 'rb') as f:
   #     data = f.read()
   # return HttpResponse(data)

   ## 方式三:把生成的图片写到内存中
   # img = Image.new('RGB', (450, 30), (123, 123, 255))
   # # 图片保存(写到内存中)
   # f=BytesIO()
   # img.save(f,'png') # 指定图片个数
   # # 打开图片
   # data=f.getvalue() # 把内容全取出来
   # return HttpResponse(data)

   ## 方法四:在图片上写文字
   # img = Image.new('RGB', (450, 30), (123, 123, 255))
   #
   # # 把图片放到画板上
   # img_draw=ImageDraw.Draw(img)
   # # 写文字
   # img_draw.text((0,0),'python')
   #
   # f=BytesIO()
   # img.save(f,'png')
   # data=f.getvalue()
   # return HttpResponse(data)

   ## 方式五:图片上写文字,字体是指定的字体,字的颜色随机
   # img = Image.new('RGB', (450, 30), (123, 123, 255))
   #
   # img_draw = ImageDraw.Draw(img)
   # img_font = ImageFont.truetype('./static/font/xgdl.ttf', 23)
   # img_draw.text((0, 0), 'python', (255, 0, 255), img_font)
   #
   # f = BytesIO()
   # img.save(f, 'png')
   # data = f.getvalue()
   # return HttpResponse(data)

   ## 方式6 最终方案
   # img = Image.new('RGB', (450, 30), get_rgb())
   img = Image.new('RGB', (450, 30), (255,255,255))

   img_draw = ImageDraw.Draw(img)
   img_font = ImageFont.truetype('./static/font/ss.TTF', 25)
   # 随机生成5个大写字母,小写字母,数字
   valid_code=''
   for i in range(5):
       low_char = chr(random.randint(97, 122))
       num_char = random.randint(0, 9)
       upper_char = chr(random.randint(65, 90))
       res = random.choice([low_char, num_char, upper_char])
       valid_code+=str(res)
       img_draw.text((i*63+50, 0), str(res), get_rgb(), img_font)
   print(valid_code)
   # 把验证码存到session中
   request.session['valid_code']=valid_code
   # 画线和点圈
   width = 450
   height = 30
   for i in range(10):
       x1 = random.randint(0, width)
       x2 = random.randint(0, width)
       y1 = random.randint(0, height)
       y2 = random.randint(0, height)
       # 在图片上画线
       img_draw.line((x1, y1, x2, y2), fill=get_rgb())

   for i in range(50):
       # 画点
       img_draw.point([random.randint(0, width), random.randint(0, height)], fill=get_rgb())
       x = random.randint(0, width)
       y = random.randint(0, height)
       # 画弧形
       img_draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_rgb())

   f = BytesIO()
   img.save(f, 'png')
   data = f.getvalue()
   return HttpResponse(data)

借助第三方

https://segmentfault.com/a/1190000017578777

5 登陆功能

后台

 

def login(request):
   if request.method == 'GET':
       return render(request, 'login.html')
   else:
       res = {'code': 100, 'msg': None}
       username = request.POST.get('username')
       password = request.POST.get('password')
       valid_code = request.POST.get('valid_code')
       # 校验验证码是否正确,忽略大小写
       if request.session.get('valid_code').upper() == valid_code.upper():
           # 不使用这个
           # models.UserInfo.objects.filter(username=username,password=password)
           user = auth.authenticate(username=username, password=password)
           if user:
               # 调用一些login
               auth.login(request, user)
               res['msg'] = '登录成功'
               res['url'] = '/index/'
           else:
               res['code'] = 101
               res['msg'] = '用户名或密码错误'
       else:
           res['code'] = 102
           res['msg'] = '验证码错误'
       return JsonResponse(res)

前台

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
   <script src="/static/jquery-3.3.1/jquery-3.3.1.min.js"></script>
   <title>登录</title>
</head>
<body>
<div class="container-fluid">
   <div class="row">
       <h1 class="text-center">登录功能</h1>
       <div class="col-md-6 col-md-offset-3">

           <form id="form">
              {% csrf_token %}

               <div class="form-group">
                   <label for="">用户名</label>
                   <input type="text" name="username" class="form-control">
               </div>
               <div class="form-group">
                   <label for="">密码</label>
                   <input type="password" name="password" class="form-control">
               </div>
               <div class="form-group">
                   <label for="">验证码</label>
                   <div class="row">
                       <div class="col-md-6">
                           <input type="text" name="valid_code" class="form-control">
                       </div>
                       <div class="col-md-6">
                           <img src="/get_valid/" height="30" width="450" id="id_valid_code">
                       </div>
                   </div>

               </div>

               <div class="text-center">
                   <input type="button" value="登录" id="id_submit" class="btn btn-danger"><span
                       class="error text-danger" style="margin-left: 10px"></span>
               </div>
           </form>
       </div>
   </div>
</div>
</body>
<script>
   $("#id_valid_code").click(function () {
       var url = $("#id_valid_code")[0].src
       $("#id_valid_code")[0].src = url + '?'
  })

   $("#id_submit").click(function () {
       //不建议在js中写模板语法
       $.ajax({
           url: '/login/',
           method: 'post',
           data: {
               'username': $('[name="username"]').val(),
               'password': $('[name="password"]').val(),
               'valid_code': $('[name="valid_code"]').val(),
               'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val()
          },
           success:function (data) {
               if(data.code==100){
                   location.href=data.url
              }else {
                   $('.error').html(data.msg)
              }

          }
      })

  })


</script>
</html>

 

6 博客首页导航条

后台

def index(request):
   return render(request, 'index.html')


def logout(request):
   auth.logout(request)
   return redirect('/')

 

前台

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
   <script src="/static/jquery-3.3.1/jquery-3.3.1.min.js"></script>
   <script src="/static/bootstrap/js/bootstrap.min.js"></script>
   <title>博客园首页</title>
</head>
<body>


<div class="head">
   <nav class="navbar navbar-default">
       <div class="container-fluid">
           <div class="navbar-header">
               <a class="navbar-brand" href="#">博客园</a>
           </div>

           <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
               <ul class="nav navbar-nav">
                   <li class="active"><a href="/index/">首页 <span class="sr-only">(current)</span></a></li>
                   <li><a href="#">新闻</a></li>

               </ul>
              {% if request.user.is_authenticated %}
                   <ul class="nav navbar-nav navbar-right">
                       <li><a href="#">{{ request.user.username }}</a></li>
                       <li class="dropdown">
                           <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
                              aria-haspopup="true" aria-expanded="false">更多 <span class="caret"></span></a>
                           <ul class="dropdown-menu">
                               <li><a href="#">修改密码</a></li>
                               <li><a href="#">修改头像</a></li>
                               <li role="separator" class="divider"></li>
                               <li><a href="/logout/">退出登录</a></li>
                           </ul>
                       </li>
                   </ul>
              {% else %}
                   <ul class="nav navbar-nav navbar-right">
                       <li><a href="/login/">登录</a></li>
                        <li><a href="/register/">注册</a></li>
                   </ul>
              {% endif %}

           </div><!-- /.navbar-collapse -->
       </div><!-- /.container-fluid -->
   </nav>
</div>
<div class="container-fluid">
   <div class="body">
       <div class="row">
           <div class="left_content col-md-2"></div>
           <div class="middle_content col-md-7"></div>
           <div class="right_content col-md-3"></div>
       </div>
   </div>
</div>

</body>
</html>

补充

异步

0 程序:躺在硬盘上就是一堆文件,加载到内存,就是一堆指令,被cpu调度执行
1 进程,线程,协程
2 进程是资源分配的最小单位   跨进程通信 IPC ,通过共享变量实现不了,借助Queue,借助文件,借助数据库,借助redis,借助消息队列(专业干这个事)
2 线程是cpu调度的最小单位(程序执行的最小单位),线程通信:共享变量(并发安全问题,锁,分布式锁,悲观锁,乐观锁)
3 协程:当线程下实现并发(保存状态+切换)
4 一旦使用了异步,后续全用异步

5 await async 关键字
async:声明协程函数
   await:io操作前面加
posted @ 2020-12-29 20:56  投降输一半!  阅读(245)  评论(0编辑  收藏  举报