zoukankan      html  css  js  c++  java
  • 博客园之登录

    from django.db import models
    from django.contrib.auth.models import AbstractUser
    class UserInfo(AbstractUser):
        """
        用户信息
        """
        nid = models.AutoField(primary_key=True)
        nickname = models.CharField(verbose_name='昵称', max_length=32)
        telephone = models.CharField(max_length=11, null=True, unique=True)
        avatar = models.FileField(upload_to = 'avatars/',default="/avatars/default.png")
        create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
        blog = models.OneToOneField(to='Blog', to_field='nid',null=True)
    
        def __str__(self):
            return self.username
    
    
    
    class Blog(models.Model):
    
        """
        博客信息
        """
        nid = models.AutoField(primary_key=True)
        title = models.CharField(verbose_name='个人博客标题', max_length=64)
        site = models.CharField(verbose_name='个人博客后缀', max_length=32, unique=True)
        theme = models.CharField(verbose_name='博客主题', max_length=32)
    
        def __str__(self):
            return self.title
    class Category(models.Model):
        """
        博主个人文章分类表
        """
        nid = models.AutoField(primary_key=True)
        title = models.CharField(verbose_name='分类标题', max_length=32)
        blog = models.ForeignKey(verbose_name='所属博客', to='Blog', to_field='nid')
    
        def __str__(self):
            return self.title
    class Tag(models.Model):
    
        nid = models.AutoField(primary_key=True)
        title = models.CharField(verbose_name='标签名称', max_length=32)
        blog = models.ForeignKey(verbose_name='所属博客', to='Blog', to_field='nid')
        def __str__(self):
            return self.title
    class Article(models.Model):
    
        nid = models.AutoField(primary_key=True)
        title = models.CharField(max_length=50, verbose_name='文章标题')
        desc = models.CharField(max_length=255, verbose_name='文章描述')
    
        comment_count= models.IntegerField(default=0)
        up_count = models.IntegerField(default=0)
        down_count = models.IntegerField(default=0)
    
        create_time = models.DateTimeField(verbose_name='创建时间')
    
        homeCategory = models.ForeignKey(to='Category', to_field='nid', null=True)
        #siteDetaiCategory = models.ForeignKey(to='SiteCategory', to_field='nid', null=True)
    
        user = models.ForeignKey(verbose_name='作者', to='UserInfo', to_field='nid')
        tags = models.ManyToManyField(
            to="Tag",
            through='Article2Tag',
            through_fields=('article', 'tag'),
        )
    
    
        def __str__(self):
            return self.title
    class ArticleDetail(models.Model):
        """
        文章详细表
        """
        nid = models.AutoField(primary_key=True)
        content = models.TextField()
        article = models.OneToOneField(to='Article', to_field='nid')
    class Comment(models.Model):
        """
        评论表
        """
        nid = models.AutoField(primary_key=True)
        article = models.ForeignKey(verbose_name='评论文章', to='Article', to_field='nid')
        user = models.ForeignKey(verbose_name='评论者', to='UserInfo', to_field='nid')
        content = models.CharField(verbose_name='评论内容', max_length=255)
        create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    
        parent_comment = models.ForeignKey('self', null=True)
    
    
        def __str__(self):
            return self.content
    class ArticleUpDown(models.Model):
        """
        点赞表
        """
        nid = models.AutoField(primary_key=True)
        user = models.ForeignKey('UserInfo', null=True)
        article = models.ForeignKey("Article", null=True)
        is_up=models.BooleanField(default=True)
    
        class Meta:
            unique_together = [
                ('article', 'user'),
            ]
    class Article2Tag(models.Model):
        nid = models.AutoField(primary_key=True)
        article = models.ForeignKey(verbose_name='文章', to="Article", to_field='nid')
        tag = models.ForeignKey(verbose_name='标签', to="Tag", to_field='nid')
    
        class Meta:
            unique_together = [
                ('article', 'tag'),
            ]
    
        def __str__(self):
            v=self.article.title+"----"+self.tag.title
            return v
    models.py配置
    AUTH_USER_MODEL = "blog01.UserInfo" #app名称.UserInfo表
    settings.py文件设置
    urls.py:

    urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login),
    url(r'^get_valid_img/', views.get_valid_img),
    url(r'^index/', views.index),

    ]
     
    views.py:
    from django.shortcuts import render,HttpResponse,redirect
    from django.contrib import auth
    from django.http import JsonResponse
    from django import forms
    
    from django.forms import widgets
    
    from .models import *
    
    
    
    def login(request):
        if request.method=="POST":
            user=request.POST.get("username")
            pwd=request.POST.get("password")
            input_valid_codes=request.POST.get("valid_code")
    
            # 校验验证码
            session_valid_codes=request.session.get("insert_valid")
            print(session_valid_codes,'222')
            '''
            request.COOKIE['sessionId'] #取出随机字符串
            in session表中
            models.session.object.filter(sessionid=取出随机字符串).values
            
            '''
            login_response={"user":None,"error_msg":""} #定义一个第三方变量存储用于判断
            if session_valid_codes.upper()==input_valid_codes.upper(): #用户在浏览器输入大小写混合、大写、小写 均转为大写进行判断。(忽略大小写)
                user=auth.authenticate(username=user,password=pwd)#再判断输入的用户名、密码与数据库存储的是否相同
                if user: #用户名密码如果为真
                    auth.login(request,user) #验证登录
                    login_response["user"]=user.username #用户名赋给login_response的 'user'
                    print(user.username)
                else:
                    login_response["error_msg"] = "username or password error!" #否则赋值给错误
            else:
                login_response["error_msg"]="valid_code error!" #输入的验证码与输入的不一致则返回error提示
            import json
            return HttpResponse(json.dumps(login_response))
        else:
            return render(request,"login.html")
    
    # Create your views here.
    # 方式1:(仅仅实现了渲染本地静态图片当做验证码的功能)
    #     from cnblog项目实战 import settings
    #     import os
    #     path=os.path.join(settings.BASE_DIR,"static","img","linhaifeng.jpg")
    #     with open(path,"rb") as f:
    #         data=f.read()
    
    #方式二要实现图片自动实现生成一张图片(缺点是保存到本地了)
     # from PIL import Image
     #    img=Image.new(mode='RGB',size=(120,30),color=(0,110,168)) #生成一张图片长宽120,30,颜色是三基色(RGB)因子调色而成
     #    img.save(  open('whq.png','wb') ) #以二进制方式读写保存这张图片
     #    with open('whq.png', 'rb') as f: #以二进制方式读图片
     #        data = f.read() #读出的结果保存赋值给data
     #    return HttpResponse(data)#交给浏览器渲染数据
    
    # 方法三实现把图片保存到内存
    #  from io import BytesIO #该模块实现了把文件保存到内存中
    #     f=BytesIO()
    #     from PIL import Image
    #     img=Image.new(mode='RGB',size=(90,30),color=(0,19,168)) #生成一张图片长宽120,30,颜色是三基色(RGB)因子调色而成
    #     img.save( f,'png') #保存这个文件的句柄+png后缀
    #     data=f.getvalue()
    #     return HttpResponse(data)#交给浏览器渲染数据
    
    import random
    def get_randon_color():
        return (random.randint(123,234),random.randint(123,234),random.randint(123,234))
    
    def get_valid_img(request):
        from PIL import Image, ImageDraw, ImageFont
        from io import BytesIO
        # 生成图片
        image = Image.new("RGB", (280, 40), get_randon_color()) #280, 40图片大小
    #
        #  #生成一枝画笔
        draw = ImageDraw.Draw(image)
        # font = ImageFont.truetype("static/font/kumo.ttf/", size=35)#指定字体,以及大小
        #生成随机数
        keep_valid_codes = ""
        for i in range(5):
            random_num = str(random.randint(0, 9))#生成0,9数字转换字符串
            random_lower_alf = chr(random.randint(97, 122))#生成大写字母
            random_upper_alf = chr(random.randint(65, 90))#生成小写字母
            random_char = random.choices([random_num, random_lower_alf, random_upper_alf])[0]#任意选一个
            print(random_char, "===")
            draw.text((20 + i * 50, 0), random_char, fill=get_randon_color())
            keep_valid_codes += random_char
        f = BytesIO() #实例化一个内存IO对象
        image.save(f, "png")#保存成png格式
        data = f.getvalue() #取图片+随机数的图片
        print(keep_valid_codes,keep_valid_codes.upper())
        s=''.join(keep_valid_codes)
        request.session['insert_valid']=s
        '''
        Django:做的事件
        1:浏览器中
            Set_cookie('sessionId','随机字符串')
        2:Django的中Django_session 表中
            sessionKey字段  sessiondata
             '随机字符串'   {insert_valid:keep_valid_codes}
        '''
        return HttpResponse(data) #返回带随机数的图片
    
    
    
    def index(request):
        return render(request,'index.html')
    <!DOCTYPE html>
    <html lang="en">
    <head>
    
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css">
        <script src="/static/js/jquery-3.1.1.js"></script>{#   jquery是js的扩展包所以用script #}
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-4 col-md-offset-3">
                <form>
                    <div class="form-group">
                        <label for="user">用户名</label>
                        <input type="text" class="form-control" id="user" placeholder="输入用户名">
                    </div>
    
                    <div class="form-group">
                        <label for="pwd">密码</label>
                        <input type="password" class="form-control" id="pwd" placeholder="输入密码">
                    </div>
    
                    <div class="form-group">
                        <label for="valid">验证码</label>
                        <div class="row">
                            <div class="col-md-3">
                                <input type="text" class="form-control" id="valid" placeholder="输入验证码">
                            </div>
    
                            <div>
                                <div class="col-md-3">
                                <img id="valid_img" width="220" height="40" src="/get_valid_img/" alt="">
                            </div>
                            </div>
    
                        </div>
    
                    </div>
                    <input type="button" class="btn btn-primary" value="submit" id="submit_btn" > <span class="error"></span>
    
    
                </form>
            </div>
        </div>
    </div>
    
    
    <script>
        // 验证码刷新
        $("#valid_img").click(function () {
            $(this)[0].src += "?"
        });
    
        // ajax请求验证
    
        $("#submit_btn").click(function () {
    
            $.ajax({
                url: "/login/",
                type: "post",
                data: {
                    "username": $("#user").val(),
                    "password": $("#pwd").val(),
                    "valid_code": $("#valid").val(),
                    "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val()
                },
                success: function (data) {   // {"user":"","error_meg":""}
                    console.log(data);
                    var data = JSON.parse(data);
                    if (data.user) {
                        // 登录成功
                        location.href = "/index/"
    
                    }
                    else {
                        $(".error").html(data.error_msg).css('color', "red")
    
                        setTimeout(function () {
                            $(".error").html("")
                        }, 1000)
                    }
                }
            })
    
        })
    </script>
    </body>
    </html>
    index.html(登录 后跳转的页面):
    <!
    DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"> <script src="/static/js/jquery-3.1.1.js"></script> </head> <body> <h3>index</h3> </body> </html>

    执行顺序:

    输入http://127.0.0.1:8000/login执行过程分析
    
    urls.py配置
        1:导入from  app01 import views 是指能调用views模块功能
        2:配置浏览器路径部分:login路径指向实际执行功能的函数
            urlpatterns = [
            url(r'^admin/', admin.site.urls),
            url(r'^login/', views.login),
            ]
    
        3:编写实现login功能函数
            3.1:导入auth模块使之支持auth验证(数据长度等)
                from django.contrib import auth
            3.2:get请求执行else分支执行
                    return render(request,"login.html")
            3.3:进入html页面:
                 3.3.1:<div class="container"> bootstrap整个盒子是居中效果
                        1: <div class="row">  container子盒子里的元素在一行显示
                                1.1:<div class="col-md-6 col-md-offset-3"> 盒子占六个栅格,向右移动三个栅格
                                        1:定制form表单盒子
                                                1.1:<div class="form-group">boostrap样式的盒子
                                                    1: <label for="user">用户名</label>:label标签使之能点击用户名时光标进入框
                                                    2:type="text" :类型为输入文本的框
                                                    3:class="form-control" :bootstrap样式
                                                    4:id="user" :设置唯一的标签用于查找,与label标签 for属性相同
                                                    5:placeholder="输入用户名":用于输入框中悬浮是显示的效果
    
                                                1.2:1.1:<div class="form-group">boostrap样式的盒子
                                                    1: <label for="pwd">密码</label>:label标签使之能点击用户名时光标进入框
                                                    2:type="password" :类型为输入以点'.'加密的框
                                                    3:class="form-control" :bootstrap样式
                                                    4:id="pwd" :设置唯一的标签用于查找,与label标签 for属性相同
                                                    5:placeholder="输入密码":用于输入框中悬浮是显示的效果
                                                1.3:1.1:<div class="form-group">boostrap样式的盒子
                                                    1: <label for="valid">密码</label>:label标签使之能点击用户名时光标进入框
                                                    2:type="text" :类型为输入文本的框
                                                    3:class="form-control" :bootstrap样式
                                                    4:id="valid" :设置唯一的标签用于查找,与label标签 for属性相同
                                                    5:placeholder="输入验证码":用于输入框中悬浮是显示的效果
                                                1.4:
                                                    1: {% csrf_token %}:设置中间件csrf验证
                                                    2:input type="button":设置一个可以自定义事件的提交按钮
                                                    3:class="btn btn-primary":boostrap蓝色控件样式
                                                    4:value="submit":button控件显示值为‘submit’字段
                                                    5:id="submit_btn":设置唯一性的标识,利于查找
    
    
            3.4:填写form表单:
                1:用户名:whq518518
                2:密码:ehfeoflenfol
                3:验证码:session_valid_codes 生成的随机字符串
                4:点击submit控件
                5:执行submit执行的事件
                    5.1:$("#login_btn").click(function () 把id=login_btn控件变成jquery属性,执行点击事件
                    5.2:执行ajax请求体
                        url:"/login/":执行login路径匹配 urls.py 的login---->执行views.py里的login函数
                        type:"post":提交给服务器数据的方式post
                        data:{
                            "user":$("#user").val(),#找到id=user的控件,并取输入框的值(val())
                            "pwd":$("#pwd").val(),#找到id=pwd的控件,并取输入框的值(val())
                            "valid_code":$("#valid").val(),#找到id=valid的控件,并取输入框的值(val())
                            "csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val() #设置中间件
                },
                6:匹配urls.py文件,指向views文件的login函数
                    urlpatterns = [
                        url(r'^login/', views.login),
                        ]
        4
            views.py文件login函数
    
                 7:request.method 与type:"post"相对比执行
                    user=request.POST.get("username") :
                        1:get("username") 与"username":$("#user").val()的"username"匹配
                        2:$("#user").val()的$("#user")查找form表单id=user的控件
                        3:("#user").val():取出form表单id="user"输入框的值
                    pwd=request.POST.get("password")
                        1:get("password") 与"password":$("#pwd").val()的"pwd"匹配
                        2:$("#pwd").val()的$("#pwd")查找form表单id=pwd的控件
                        3:("#pwd").val():取出form表单id="pwd"输入框的值
                    pwd=request.POST.get("valid_code")
                        1:get("valid_code") 与"valid_code":$("#valid").val()的"valid_code"匹配
                        2:$("#valid").val()的$("#valid")查找form表单id=valid的控件
                        3:("#valid").val():取出form表单id="valid"输入框的值
    
                 # 校验验证码
                    session_valid_codes=request.session.get("insert_valid")#读取session,找到insert_valid为key的一条字段
                        session读取过程:
                                '''
                                request.COOKIE['sessionId'] #取出随机字符串
                                in session表中
                                models.session.object.filter(sessionid=取出随机字符串).values
    
                                '''
                    login_response={"user":None,"error_msg":""} #定义一个第三方变量存储用于判断
                    if session_valid_codes.upper()==input_valid_codes.upper(): #判断验证码与输入的是否一致(此处必须转换成大写 或小写,不知为什么)
                        user=auth.authenticate(username=user,password=pwd)#再判断输入的用户名、密码与数据库存储的是否相同
                        if user: #用户名密码如果为真
                            auth.login(request,user) #验证登录
                            login_response["user"]=user.username #用户名赋给login_response的 'user’
                        else:
                            login_response["error_msg"] = "username or password error!" #否则赋值给错误
                    else:
                        login_response["error_msg"]="valid_code error!" #输入的验证码与输入的不一致则返回error提示
                    import json
                    return HttpResponse(json.dumps(login_response))
                        #login_response 是个字典 ,需要把结果传递给前端,前端是html、js、语言。
                        # 这就涉及到不同语言之间传递数据的问题了
                        #解决方案:1先序列化到硬盘上json.dumps(login_response)
                           # 2  用HttpResponse把序列化到硬盘上的数据传递给前端。
                            # 3请求的数据体:data: {}
    
                            #4: success: function(data) 返回的数据
                            # var data = JSON.parse(data); 把data数据:login_response={"user":None,"error_msg":""}解析成JavaScript对象
                            # if (data.user) { 判断字典user是否为真
                            # // 登录成功
                            # location.href = "/index/"为真则登录index页面
                            #
                            # }
                            # else { 为假则找到button按钮的后的 span标签 class=error,
            #                       渲染data.error_msg字段,标红显示。
                            # $(".error").html(data.error_msg).css('color', "red")
                            #
                            # setTimeout(function () {1秒后超时,找到button按钮的后的 span标签 class=error 消失
                            # $(".error").html("")
                            # }, 1000)
                            # }
                            # }
                else:
                    return render(request,"login.html")
    
            创建get_randon_color()函数:(RGB颜色以随机数方式生成)
                    import random
            def get_randon_color():
                return (random.randint(123,234),random.randint(123,234),random.randint(123,234))
            ------------------------------------------------------------------------------------------
            创建get_valid_img()函数:(实现图片随机验证码)
                def get_valid_img(request):
                    from PIL import Image, ImageDraw, ImageFont
                    from io import BytesIO
                    # 生成图片
                    image = Image.new("RGB", (280, 40), get_randon_color()) #长宽280, 40图片大小
                #
                    #  #生成一枝画笔
                    draw = ImageDraw.Draw(image)
                    # font = ImageFont.truetype("static/font/kumo.ttf/", size=35)#指定字体,以及大小
                    #生成随机数
                    keep_valid_codes = ""
                    for i in range(5):
                        random_num = str(random.randint(0, 9))#生成0,9数字转换字符串
                        random_lower_alf = chr(random.randint(97, 122))#生成大写字母
                        random_upper_alf = chr(random.randint(65, 90))#生成小写字母
                        random_char = random.choices([random_num, random_lower_alf, random_upper_alf])[0]#,不以切片方式话,结果是列表类型
                        print(random_char, "===")
                        draw.text((20 + i * 50, 0), random_char, fill=get_randon_color()) #在图片20像素处,每增加一个元素字符占50像素,y轴处于0坐标
                        keep_valid_codes += random_char #生成5位的字符串
    
                    f = BytesIO() #实例化一个内存IO对象
                    image.save(f, "png")#保存成png格式
                    data = f.getvalue() #取图片+随机数=的图片
    
                    request.session['insert_valid']=keep_valid_codes
                            #把生成的随机字符串插入session表中(
                            解决方案:1 保存在内存中:B链接来了会重置验证码,导致A客户端在填写form表单时就重置了其他导致验证码错误
                                      2:保存在本地:不可取,保存在客户端的某地不方便
                                      3:保存到session表中:登录时直接从数据库查询读取
                            )
                                            '''
                                            Django:做的事件
                                            1:浏览器中
                                                Set_cookie('sessionId','随机字符串')
                                            2:Django的中Django_session 表中
                                                sessionKey字段  sessiondata
                                                 '随机字符串'   {insert_valid:keep_valid_codes}
                                            '''
                    return HttpResponse(data) #返回带随机数的图片
    
    
            ----------------------------------------------------------------------------------
                def index(request):
                    return render(request,'index.html')
    步骤之登录执行过程

      开发者自己写input标签时 用键(name):值(value) +submit表单形式提交给服务器,换做ajax后就改成" username": $("#user") "username":就相当于input框的name属性 值就变成了("#pwd").val() 用户输入的值 例如: "username": $("#user").val(), 相当于form表单的name属性 "password": $("#pwd").val(), "valid_code": $("#valid").val(), 

  • 相关阅读:
    HTML基础学习笔记
    CSS-精灵图片的使用(从一张图片中截图指定位置图标)
    侧边栏显示
    HTML <form> action 属性
    2018年寒假小记
    算法提高--接水问题
    基础练习--huffman
    ...
    基础算法
    枚举--最长单词--蓝桥杯
  • 原文地址:https://www.cnblogs.com/wanghuaqiang/p/8471109.html
Copyright © 2011-2022 走看看