• day 75天 bbs 项目第一天 ,auth登陆


    from django.db import models
    
    from django.contrib.auth.models import AbstractUser
    
    class UserInfo(AbstractUser):
        '''
        用户表
        '''
        nid  =models.AutoField(primary_key=True)
        phone  =models.CharField(max_length=11,null=True,unique=True)
        avatar = models.FileField(upload_to='avatars/',default='avatars/default.png',verbose_name='头像')
        create_time =models.DateTimeField(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(max_length=64)
        site =models.CharField(max_length=32,unique=True)
        theme =models.CharField(max_length=32)
    
        def __str__(self):
            return self.title
    
    
    class  Category(models.Model):
        '''
        个人博客文章分类
        '''
        nid =models.AutoField(primary_key=True)
        title =models.CharField(max_length=32)#分类标题
        blog = models.ForeignKey(to ='Blog',to_field='nid')#外键关联博客,一个博客站点可以有多个分类
    
        def __str__(self):
            return self.title
    
    class Tag(models.Model):
        ''''
        标签
        '''
        nid =models.AutoField(primary_key=True)
        title =models.CharField(max_length=32)
        blog =models.ForeignKey(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) #文章标题描述
        desc =models.CharField(max_length=255) #文章描述
        create_time =models.DateTimeField()#创建时间
    
        category = models.ForeignKey(to ='Category',to_field='nid',null=True)
        user = models.ForeignKey(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 Article2Tag(models.Model):
        '''
        文章和标签的多对多关系表
        '''
        nid =models.AutoField(primary_key=True)
        article =models.ForeignKey(to='Article',to_field='nid')
        tag =models.ForeignKey(to ='Tag',to_field='nid')
    
        class Meta:
            unique_together = (('article','tag'),)
    
    class ArticleUpDown(models.Model):
        '''
        点赞
        '''
        nid= models.AutoField(primary_key=True)
        user =models.ForeignKey(to ='UserInfo',null=True)
        artcle = models.BooleanField(default=True)
    
        class  Meta:
            unique_together = (('article','user'),)
    
    class Comment(models.Model):
        '''
        评论表
        '''
        nid = models.AutoField(primary_key=True)
        article =models.ForeignKey(to ='Article',to_field='nid')
        user =models.ForeignKey(to ='UserInfo',to_field='nid')
        content =models.CharField(max_length=255)#评论内容
        create_time =models.DateTimeField(auto_now_add=True)
        parent_comment =models.ForeignKey('self',null=True)
    
        def __str__(self):
            return self.content
    

     

    settings 里配置 

    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/1.11/howto/static-files/
    
    STATIC_URL = '/static/'
    STATICFILES_DIRS=[
        os.path.join(BASE_DIR,'static')
    ]
    
    # 告诉Djanog 项目用哪张表做认证
    AUTH_USER_MODEL='app01.UserInfo'
    
    # Database
    # https://docs.djangoproject.com/en/1.11/ref/settings/#databases
    
    DATABASES = {
        # 'default': {
        #     'ENGINE': 'django.db.backends.sqlite3',
        #     'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        # },
    
        'default':{
            'ENGINE':'django.db.backends.mysql',
            'NAME':'day77',
            'USER':'root',
            'PASSWORD':'123456',
            'HOST':'127.0.0.1',
            'PORT':3306,
    
        }
    }

    init配置文件

    import pymysql
    pymysql.install_as_MySQLdb()
    


    登录配置 

    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login/',views.login)
    ]
    

      

    login登陆页面 

     

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>欢迎登陆</title>
        <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
        <link rel="stylesheet" href="/static/mystyle.css">
        #导入bootstrap
    </head>
    <body>
    
    <div class="container">
        <div class="row">
            <form class="form-horizontal col-md-6 col-md-offset-3 login-form"  >
                {% csrf_token %}    登陆界面的csrf token校验
                <div class="form-group" >
                    <label for="inputEmail3" class="col-sm-2  control-label">用户名:</label>
                    <div class="col-sm-10">
                        <input type="text" class="form-control" id="username" name="username" placeholder="用户名">
                    </div>
                </div>
                <div class="form-group">
                    <label for="password" class="col-sm-2 control-label">密码</label>
                    <div class="col-sm-10">
                        <input type="password" class="form-control" id="password" name="password" placeholder="密码">
                    </div>
                </div>
    {#            <div class="form-group">#}
    {#                <div class="col-sm-offset-2 col-sm-10">#}
    {#                    <div class="checkbox">#}
    {#                        <label>#}
    {#                            <input type="checkbox"> 记住密码#}
    {#                        </label>#}
    {#                    </div>#}
    {#                </div>#}
    {#            </div>#}
                <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                        <button type='button' class="btn btn-default" id="login-button">登陆</button>
                        <span class="login-error"></span>
                    </div>
                </div>
            </form>
        </div>
    </div>
    
    <script src="/static/jquery-3.3.1.js"></script>
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>
    
    <script>
        $('#login-button').click(function(){
            // 1.取到用户填写的用户名和密码:-->取input框的值
            var username = $('#username').val();
            var password =$('#password').val();
            //2. 用AJAX 发送到服务器端.
            $.ajax({
                url:'/login/',
                type:'post',
                data:{ 'username':username,
                       'password': password ,
                       'csrfmiddlewaretoken': $("[name='csrfmiddlewaretoken']").val()
                     },
                success:function (data) {
                    console.log(data);
                    if (data.status){
                        //有错误,在页面中提示
                        $(".login-error").text(data.msg)
                    }else {
                        //登陆成功
                        location.href = data.msg
                    }
    
                }
            })
    
        })
    })
    //当input框获取焦点时将之前的错误信息清空
    $("#username,#password") .focus(function () {
    //将之前的内容清空
    $('.login-error').text('');
    })
    </script>  
    </body>
    </html>

      

    views文件

     

    from django.shortcuts import render,redirect,HttpResponse
    from   django.http import JsonResponse
    from django.contrib import  auth
    
    # Create your views here.
    
    def login(request):
        # if request.is_ajax():
        if request.method =='POST':
            print(request.POST)
    
            #初始化一个给ajax返回的数据
            ret ={'status':0,'msg':''}
            #从提交过来的数据中取到用户名和密码
            username =request.POST.get('username')
            pwd =request.POST.get('password')
            #利用auth模块进行验证 导入auth模块
            user = auth.authenticate(username=username, password =pwd)
            if user:
                #用户名密码正确 ,登陆成功.
                #给用户做登陆
                auth.login(request,user)
                ret['msg']='/index/'
                return JsonResponse(ret)
                #跳转到index 界面
            else:
                #用户名密码错误,
                ret['status'] =1
                ret['msg']='用户名或密码错误'
                return JsonResponse(ret)
        return render(request,'login.html'
            )
    
    def index(request):
        return  HttpResponse('ok')
    

      

    二、生成验证码图片

    验证码:

    1. 验证码要随机生成

      1.如何自己生成一个图片

      2. PIL Pillow  

    views 文件配置

    #获取验证码图片的视图
    def get_valid_img(request):
        with open( 'valid_code.png','rb') as f :
            data =f.read()
            #自己生成一个图片
            from PIL import Image,ImageDraw,ImageFont
            import random
    
    
            #获取随机颜色的函数
            def get_random_color():
                return random.randint(0,255),
                 random.randint(0, 255),
                random.randint(0, 255),
    
            #生成一个图片对象
            img_obj = Image.new(
                'RGB',
                (220,35),
                get_random_color()
            )
            #在生成的图片上写字符
            #生成一个画笔对象
            draw_obj =ImageDraw.Draw(img_obj)
            #加载字体文件,得到一个字体对象
            font_obj = ImageFont.truetype("static/font/kumo.ttf",28)
            #循环五次添加随机字符
            valid_code_tmp =[]
            for i in range(5):
                n =str(random.randint(0,9))
                l=chr(random.randint(97,122))
                u=chr(random.randint(65,90))
                tmp = random.choice([n,l,u])
                valid_code_tmp.append(tmp)
                draw_obj.text((20+40*i,0),tmp,fill=get_random_color(),font =font_obj)
            #将生成的图片保存在磁盘上.
            # with open( 's10.png','wb') as f :
            #   img_obj.save(f,"png")
            #     #把刚才生成的图片返回给页面
            # with open('s10.png','rb')as f :
            #     data =f.read()
    
            #不需要在硬盘上保存文件,直接在内存中加载就可以
            from io import  BytesIO
            io_obj =BytesIO()
            #将生成的图片数据保存在io对象中
            img_obj.save(io_obj,'png')
            #从io对象里面取上一步保存的数据
            data =io_obj.getvalue()
            return HttpResponse(data)
    

      

    Login登陆页面配置

     <div class="form-group">
                    <label for="password" class="col-sm-2 control-label">密码</label>
                    <div class="col-sm-10">
                        <input type="password" class="form-control" id="password" name="password" placeholder="密码">
                    </div>
                </div>
    
                   <div class="form-group">
                    <label for="password" class="col-sm-2 control-label">验证码</label>
                    <div class="col-sm-10">
                        <input type="text"  name="valid_code" >
                        <img class="valid-img" src="/get_valid_img/" alt="">
                    </div>
                </div>
    
                <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                        <button type='button' class="btn btn-default" id="login-button">登陆</button>
                        <span class="login-error"></span>
                    </div>
                </div>
    

      

    老师写的登录view文件

    from django.shortcuts import render, redirect, HttpResponse
    from django.http import JsonResponse
    from django.contrib import auth
    # Create your views here.
    
    # VALID_CODE = ""
    
    
    def login(request):
        # if request.is_ajax():  # 如果是AJAX请求
        if request.method == "POST":
            # 初始化一个给AJAX返回的数据
            ret = {"status": 0, "msg": ""}
            # 从提交过来的数据中 取到用户名和密码
            username = request.POST.get("username")
            pwd = request.POST.get("password")
            valid_code = request.POST.get("valid_code")  # 获取用户填写的验证码
            print(valid_code)
            print("用户输入的验证码".center(120, "="))
            if valid_code and valid_code.upper() == request.session.get("valid_code", "").upper():
                # 验证码正确
                # 利用auth模块做用户名和密码的校验
                user = auth.authenticate(username=username, password=pwd)
                if user:
                    # 用户名密码正确
                    # 给用户做登录
                    auth.login(request, user)
                    ret["msg"] = "/index/"
                else:
                    # 用户名密码错误
                    ret["status"] = 1
                    ret["msg"] = "用户名或密码错误!"
            else:
                ret["status"] = 1
                ret["msg"] = "验证码错误"
    
            return JsonResponse(ret)
        return render(request, "login.html")
    
    
    def index(request):
        return render(request, "index.html")
    
    
    # 获取验证码图片的视图
    def get_valid_img(request):
        # with open("valid_code.png", "rb") as f:
        #     data = f.read()
        # 自己生成一个图片
        from PIL import Image, ImageDraw, ImageFont
        import random
    
        # 获取随机颜色的函数
        def get_random_color():
            return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
    
        # 生成一个图片对象
        img_obj = Image.new(
            'RGB',
            (220, 35),
            get_random_color()
        )
        # 在生成的图片上写字符
        # 生成一个图片画笔对象
        draw_obj = ImageDraw.Draw(img_obj)
        # 加载字体文件, 得到一个字体对象
        font_obj = ImageFont.truetype("static/font/kumo.ttf", 28)
        # 开始生成随机字符串并且写到图片上
        tmp_list = []
        for i in range(5):
            u = chr(random.randint(65, 90))  # 生成大写字母
            l = chr(random.randint(97, 122))  # 生成小写字母
            n = str(random.randint(0, 9))  # 生成数字,注意要转换成字符串类型
    
            tmp = random.choice([u, l, n])
            tmp_list.append(tmp)
            draw_obj.text((20+40*i, 0), tmp, fill=get_random_color(), font=font_obj)
    
        print("".join(tmp_list))
        print("生成的验证码".center(120, "="))
        # 不能保存到全局变量
        # global VALID_CODE
        # VALID_CODE = "".join(tmp_list)
    
        # 保存到session
        request.session["valid_code"] = "".join(tmp_list)
        # 加干扰线
        # width = 220  # 图片宽度(防止越界)
        # height = 35
        # for i in range(5):
        #     x1 = random.randint(0, width)
        #     x2 = random.randint(0, width)
        #     y1 = random.randint(0, height)
        #     y2 = random.randint(0, height)
        #     draw_obj.line((x1, y1, x2, y2), fill=get_random_color())
        #
        # # 加干扰点
        # for i in range(40):
        #     draw_obj.point((random.randint(0, width), random.randint(0, height)), fill=get_random_color())
        #     x = random.randint(0, width)
        #     y = random.randint(0, height)
        #     draw_obj.arc((x, y, x+4, y+4), 0, 90, fill=get_random_color())
    
        # 将生成的图片保存在磁盘上
        # with open("s10.png", "wb") as f:
        #     img_obj.save(f, "png")
        # # 把刚才生成的图片返回给页面
        # with open("s10.png", "rb") as f:
        #     data = f.read()
    
        # 不需要在硬盘上保存文件,直接在内存中加载就可以
        from io import BytesIO
        io_obj = BytesIO()
        # 将生成的图片数据保存在io对象中
        img_obj.save(io_obj, "png")
        # 从io对象里面取上一步保存的数据
        data = io_obj.getvalue()
        return HttpResponse(data)

    自己写的整个登录界面

     

    from django.shortcuts import render,redirect,HttpResponse
    from   django.http import JsonResponse
    from django.contrib import  auth
    
    # Create your views here.
    VALID_CODE=''
    def login(request):
        # if request.is_ajax():
        if request.method =='POST':
            print(request.POST)
            #初始化一个给ajax返回的数据
            ret ={'status':0,'msg':''}
            #从提交过来的数据中取到用户名和密码
            username =request.POST.get('username')
            pwd =request.POST.get('password')
            valid_code = request.POST.get('valid_code')#获取用户填写的验证码
            print(valid_code)
            print('用户输入的验证码'.center(120,'='))
            if valid_code.upper() ==request.session["valid_code"].upper():
                #利用auth模块进行验证 导入auth模块
                user = auth.authenticate(username=username, password =pwd)
                if user:
                    #用户名密码正确 ,登陆成功.
                    #给用户做登陆
                    auth.login(request,user)
                    ret['msg']='/index/'
                    return JsonResponse(ret)
                    #跳转到index 界面
                else:
                    #用户名密码错误,
                    ret['status'] =1
                    ret['msg']='用户名或密码错误'
                    return JsonResponse(ret)
        return render(request,'login.html'
            )
    
    def index(request):
        return  HttpResponse('ok')
    
    #获取验证码图片的视图
    def get_valid_img(request):
        with open( 'valid_code.png','rb') as f :
            data =f.read()
            #自己生成一个图片
            from PIL import Image,ImageDraw,ImageFont
            import random
    
            #获取随机颜色的函数
            def get_random_color():
                return random.randint(0,255),
                 random.randint(0, 255),
                random.randint(0, 255),
    
            #生成一个图片对象
            img_obj = Image.new
                    (
                'RGB',
                (220,35),
                get_random_color()
            )
            #在生成的图片上写字符
            #生成一个画笔对象
            draw_obj =ImageDraw.Draw(img_obj)
            #加载字体文件,得到一个字体对象
            font_obj = ImageFont.truetype("static/font/kumo.ttf",28)
            #循环五次添加随机字符
            valid_code_tmp =[]
            for i in range(5):
                n =str(random.randint(0,9))
                l=chr(random.randint(97,122))
                u=chr(random.randint(65,90))
                tmp = random.choice([n,l,u])
                valid_code_tmp.append(tmp)
                draw_obj.text((20+40*i,0),tmp,fill=get_random_color(),font =font_obj)
    
            print("".join(valid_code_tmp))
            print("生成的验证码".center(120, "="))
                # 不能保存到全局变量
                # global VALID_CODE
                # VALID_CODE = "".join(tmp_list)
                # 保存到session
            request.session["valid_code"] = "".join(valid_code_tmp)
    
            #将生成的图片保存在磁盘上.
            # with open( 's10.png','wb') as f :
            #   img_obj.save(f,"png")
            #     #把刚才生成的图片返回给页面
            # with open('s10.png','rb')as f :
            #     data =f.read()
    
            #不需要在硬盘上保存文件,直接在内存中加载就可以
            from io import  BytesIO
            io_obj =BytesIO()
            #将生成的图片数据保存在io对象中
            img_obj.save(io_obj,'png')
            #从io对象里面取上一步保存的数据
            data =io_obj.getvalue()
            return HttpResponse(data)
    

      

    前端登录

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>欢迎登陆</title>
        <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
        <link rel="stylesheet" href="/static/mystyle.css">
        #导入bootstrap
    </head>
    <body>
    
    <div class="container">
        <div class="row">
            <form class="form-horizontal col-md-6 col-md-offset-3 login-form"  >
                {% csrf_token %}
                <div class="form-group" >
                    <label for="inputEmail3" class="col-sm-2  control-label">用户名:</label>
                    <div class="col-sm-10">
                        <input type="text" class="form-control" id="username" name="username" placeholder="用户名">
                    </div>
                </div>
                <div class="form-group">
                    <label for="password" class="col-sm-2 control-label">密码</label>
                    <div class="col-sm-10">
                        <input type="password" class="form-control" id="password" name="password" placeholder="密码">
                    </div>
                </div>
    
                   <div class="form-group">
                    <label for="password" class="col-sm-2 control-label">验证码</label>
                    <div class="col-sm-10">
                        <input type="text"  name="valid_code" id="valid_code" >
                        <img class="valid-img" src="/get_valid_img/" alt="">
                    </div>
                </div>
    
                <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                        <button type='button' class="btn btn-default" id="login-button">登陆</button>
                        <span class="login-error"></span>
                    </div>
                </div>
            </form>
        </div>
    </div>
    
    <script src="/static/jquery-3.3.1.js"></script>
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>
    
    <script>
        $('#login-button').click(function(){
            // 1.取到用户填写的用户名和密码:-->取input框的值
            var username = $('#username').val();
            var password =$('#password').val();
            var valid_code=$('#valid_code').val();
    
            //2. 用AJAX 发送到服务器端.
            $.ajax({
                url:'/login/',
                type:'post',
                data:{ 'username':username,
                       'password': password ,
                        'valid_code':valid_code,
                       'csrfmiddlewaretoken': $("[name='csrfmiddlewaretoken']").val()
                     },
                success:function (data) {
                    console.log(data);
                    if (data.status){
                        //有错误,在页面中提示
                        $(".login-error").text(data.msg)
                    }else {
                        //登陆成功
                        location.href = data.msg
                    }
    
                }
            })
    
        })
            //当input框获取焦点时将之前的错误信息清空
        $("#username,#password") .focus(function () {
            //将之前的内容清空
            $('.login-error').text('');
        })
    
    </script>
    
    </body>
    </html>
    

      

  • 相关阅读:
    C# 的 TOML 库
    测试龙芯 LoongArch .NET之 使用 FastTunnel 做内网穿透远程计算机
    开源的负载测试/压力测试工具 NBomber
    .NET 6 Preview 6 正式发布: 关注网络开发
    .NET 5.0 Docker 镜像 错误修复方法
    [LeetCode] 1191. K-Concatenation Maximum Sum K次串联后最大子数组之和
    [LeetCode] 1190. Reverse Substrings Between Each Pair of Parentheses 反转每对括号间的子串
    [LeetCode] 1189. Maximum Number of Balloons 气球的最大数量
    [LeetCode] 1187. Make Array Strictly Increasing 使数组严格递增
    [LeetCode] 1186. Maximum Subarray Sum with One Deletion 删除一次得到子数组最大和
  • 原文地址:https://www.cnblogs.com/mengbin0546/p/9084401.html
Copyright © 2020-2023  润新知