• auth复习和BBS项目的登录(1)


     

    auth复习

    auth组件
        验证:authenticate(request,username='andy',password='123)
        登录:login(request,user)
        注销:login(request),内部调用了flush(),以后再从 request中取出user,是匿名函数
        request.user:请求来了.在中间件中.通过cookie查询user信息,放到request.user中,如果查询不到,把匿名客户赋值给他
        登录认证装饰器:login_required(制定?后面拼接的是key值,如果没有完整登录,跳转到拿个url)
            全局配置跳转的url:在setting中:LOGIN_URL='/login/'
            
        创建用户:create_superuser,creat_user,就只是一个字段区分
        校验密码:check_password(密码),得用户对象调用,如果校验通过.,返回True
        修改密码:set_password(密码),修改了一定要调save方法.得用户对象来调用
        是否通过验证通过:is_authenticated,校验用户是否验证通过,通常用在模板上
        删除用户:orm的删除
        
        扩展auth组件:
            创建一个一对一的表模型,写扩展的字段
            定义一个表模型,继承AbstractUser,写扩展的字段,
            数据库迁移会报错,取setting中配置:AUTH_USER_MODEL="app名字,表模型"
            其他用法完全一致,知识原来用User表模型,现在改成新定义的表模型

    关于创建项目的事项

    在settings 中填写数据库相关信息,如果是MySql数据库的话

    DATABASES = {
        # 'default': {
        #     'ENGINE': 'django.db.backends.sqlite3',
        #     'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        # }
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'bbs',
            'HOST': '127.0.0.1',
            'PORT': 3306,
            'USER': 'root',
            'PASSWORD': 'admin',
        }
    }

    记得在__init__.py中配置

    import pymysql
    pymysql.install_as_MySQLdb()

    最好在settings中设置

    STATIC_URL = '/static/'
    
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, 'static'),
    )
    
    AUTH_USER_MODEL = 'blog.UserInfo'

    BBS项目

    1 数据结构分析

    从上图我们看出

    ①UserInfo----Blog 一个用户表对应一个站点表,他们之间是一对一的关系,所以在任何一张表上加表关系都行

    blog=models.OneToOneField(to='Blog',to_field='nid')

    ②Blog---Category 一个用户表也就是一个站点表对应多个文章分类,他们之间是一对多的关系,关联数据加在Category中,即

    blog=models.ForeignKey(to="Blog",to_field='nid',null=True)

    ③Blog---Tag  一个用户表也就是一个站点表对应多个文章标签表,他们之间是一对多的关系,关联数据加在Tag中,即

    blog=models.ForeignKey(to="Blog",to_field='nid',null=True)

    ④ Category---Article一个文章分类对应多个文章(比如一个Python目录下有多个关于python的文章),他们之间是一对多的关系,关系数据加在Article中,即

     category=models.ForeignKey(to="Category",to_field='nid',null=True)

    ⑤Tag---Article:一个标签对应多个文章,一篇文章可以有多个标签,他们是多对多的关系,我们可以创建第三张表,将Tag和Article都加进去

    tag=models.ManyToManyField(to="Tag",through="ArticleTOTage",through_fields=('article','tag'))# 在Article中
    # 手动创建第三张表
    class ArticleTOTage(models.Model):
        nid=models.AutoField(primary_key=True)
        article=models.ForeignKey(to='Article',to_field='nid')
        tag=models.ForeignKey(to='Tag',to_field='nid'

    ⑥UserInfo---UpAndDown 一个用户可以给不同的文章点赞,一个赞对应一个用户,所以用户和点赞,点踩与是一对多的关系,将关系创建在UpAndDown这张表中,即

    user = models.ForeignKey(to='UserInfo', to_field='nid')

    UpandDown---Article  一篇文章可以有很多的点赞数,每一个赞值对应一篇文章.,所以点赞和文章是一对多的关系,将关系表创建在UpAndDown这张表中,即

    article = models.ForeignKey(to='Article', to_field='nid')

    ⑦Commit---UserInfo; 一个用户可以发很多评论,一个评论对应一个用户,所以用户和评论与是一对多的关系,将关系创建在Commit这张表中,即

    user=models.ForeignKey(to='UserInfo',to_field='nid')

    Commit---Article 一篇文章有很多的评论,即文章很评论是一对多的关系,将表建在Commit中

    article=models.ForeignKey(to='Article',to_field='nid')

     ⑧ Blog---Article  个人站点和文章之间是一对多的关系,一个站点对应写不同的文章,将关系表写在Article中

    blog=models.ForeignKey(to='blog',to_field='nid',null=True)

    model.py

    from django.db import models
    from django.contrib.auth.models import AbstractUser
    
    # Create your models here.
    
    # UserInfo 这个表,继承AbstracUser,因为要用suth组件
    class UserInfo(AbstractUser):
        nid=models.AutoField(primary_key=True)
        # username=models.CharField(max_length=32,unique=True)
    
        phone=models.CharField(max_length=32,null=True)
        # 图像
        avatar=models.FileField(upload_to='avatar/',default='/static/img/default.png')
        # 个人站点
        blog=models.OneToOneField(to='Blog',to_field='nid')
    
    
    class Blog(models.Model):#个人站点
        nid=models.AutoField(primary_key=True)
        title=models.CharField(max_length=64)# 标题
        site_name=models.CharField(max_length=32)#站点名
        theme=models.CharField(max_length=64)#主题
    
    class Category(models.Model):#文章分类表
        nid = models.AutoField(primary_key=True)
        title = models.CharField(max_length=64)  # 标题
        blog=models.ForeignKey(to="Blog",to_field='nid',null=True)
    
    class Tag(models.Model):# 文章标签表
        nid = models.AutoField(primary_key=True)
        title = models.CharField(max_length=64)  # 标题
        blog=models.ForeignKey(to='Blog',to_field='nid',null=True)
    
    
    class Article(models.Model):# 文章表
        nid=models.AutoField(primary_key=True)
        title=models.CharField(max_length=64)
        desc=models.CharField(max_length=255)
        # 大文本
        content=models.TextField()
        # 创建时间,auto_now_add指的是把当前时间加上
        create_time=models.DateTimeField(auto_now_add=True)
        category=models.ForeignKey(to="Category",to_field='nid',null=True)
        blog=models.ForeignKey(to='blog',to_field='nid',null=True)
    
    
        tag=models.ManyToManyField(to="Tag",through="ArticleTOTage",through_fields=('article','tag'))
    
    
    
    
    # 手动创建第三张表
    class ArticleTOTage(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 Commit(models.Model):
        nid=models.AutoField(primary_key=True)
        user=models.ForeignKey(to='UserInfo',to_field='nid')
        article=models.ForeignKey(to='Article',to_field='nid')
        content=models.CharField(max_length=32)
        create_time=models.DateTimeField(auto_now_add=True)
        # 自关联
        parent_id=models.ForeignKey(to='self',to_field='nid')
    
    
    class UpAndDown(models.Model):
        nid = models.AutoField(primary_key=True)
        user = models.ForeignKey(to='UserInfo', to_field='nid')
        article = models.ForeignKey(to='Article', to_field='nid')
        is_up=models.BooleanField()
        class Meta:
            # 写这些是为了不写脏数据,联合唯一
            unique_together=(('user','article'),)
    创建数据库

    2 登录前端知识小结

    login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <script src="/static/jQuery-3.3.1.js"></script>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    
        <title>Title</title>
    </head>
    <body>
    
    {#container-fluid 可以自适应大小#}
    <div class="container-fluid">
    
        {#    用了class='row'才能用栅格系统#}
        <div class="row">
            {#        总共12个,占了6个,表格放在了中间#}
            <div class="col-md-6 col-md-offset-3">
                <form>
                    <h1>登录</h1>
                    <meta charset="UTF-8">
                    <div class="form-group">
                        {#                    将for里面协商input里面的id ,点击label就会跳到对应的input框里面#}
                        <label for="name">用户名</label>
                        {#                    class="form-control" 会独占一行#}
                        <input type="text" id="name" class="form-control">
                    </div>
    
                    <div class="form-group">
                        <label for="">密码</label>
                        <input type="password" id="pwd" class="form-control">
                    </div>
    
                    <div class="form-group">
                        <label for="">验证码</label>
                        <div class="row">
                            <div class="col-md-6">
                                <input type="text" id="valid_code" class="form-control">
                            </div>
    
                            <img height="35" width="300" src="/get_value_code/" alt="">
                        </div>
                    </div>
                    {#class="btn btn-primary" 生成一个蓝色的按钮 #}
                    {#                class="pull-right" 按扭靠向最右边#}
                    <input type="submit" value="登录" class="btn btn-primary pull-right">
    
                </form>
            </div>
        </div>
    </div>
    </body>
    </html>
    View Code
    知识点概括

    1 container-fluid 可以自适应大小 2 总共12个,占了6个,表格放在了中间 <div class="col-md-6 col-md-offset-3"> 3 {#将for里面协商input里面的id ,点击label就会跳到对应的input框里面#} <label for="name">用户名</label> 4 {#class="form-control" 会独占一行#} <input type="text" id="name" class="form-control"> 5 class="btn btn-primary" 生成一个蓝色的按钮 #} {# class="pull-right" 按扭靠向最右边#} <input type="submit" value="登录" class="btn btn-primary pull-right">

    验证码代码实例

    from django.shortcuts import render, HttpResponse
    from PIL import Image,ImageDraw,ImageFont
    import random
    # 管理bytes,从内存中读取数据:
    # https://www.cnblogs.com/liuqingzheng/articles/10023849.html
    from io import BytesIO
    
    
    # Create your views here.
    
    def get_random_color():
        return (
            random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
        )
    
    
    def login(request):
        if request.method == 'GET':
            return render(request, 'login.html')
    
    
    def get_value_code(request):
        # with open('static/img/lhf.jpg','rb')as f:
        # 第一种方式
        # data=f.read()
        # return HttpResponse(data)
        # 第二种方式 随机生成一张图片
        #  pip3 imstall Pillow
        # Pillow是一个图像处理模块,功能很强大
    
        # 第二种方式
        # 生成一张图片
        # img = Image.new('RGB', (320, 35), color=get_random_color())
        # # 保存到本地
        # with open('valid_code.png', 'wb')as f:
        #     img.save(f, 'png')
        #
        # with open('valid_code.png', 'rb')as f:
        #     data = f.read()
        #     return HttpResponse(data)
    
        # 第三种方式
        # img = Image.new('RGB', (320, 35), color=get_random_color())
        # # 在内存中生成一个文件,速度快
        # f = BytesIO()  # 相当于在内存中打开了一个空文件
        # # 把图片保存到f中
        # img.save(f, 'png')
        # data = f.getvalue()
        #
        #
        # return HttpResponse(data)
    
        # 第四种方式
        img=Image.new("RGB",(320,35),color=get_random_color())
        # 拿到画笔,把图片传到画笔
        img_draw=ImageDraw.Draw(img)
        # 生成一个字体对象,第一个参数是字体文件的路径,第二个参数是字体大小
        font=ImageFont.truetype('static/font/ss.TTF',size=25)
    
        # 第一个参数:xy的坐标,第二个参数:要写的文字,第三个参数:写文字的颜色,第四个参数:字体
    
        img_draw.text((0,0),'python',get_random_color(),font=font),
        # 联合唯一
        f=BytesIO()
        img.save(f,'png')
        data=f.getvalue()
        return HttpResponse(data)
    View Code

    图片验证第一种方式

    with open('static/img/lhf.jpg','rb')as f:
    data=f.read()
    return HttpResponse(data)

    图片验证第二种方式

    #  pip3 imstall Pillow 安装pillow模块
     Pillow是一个图像处理模块,功能很强大
    from PIL import Image
    import random
    
    def get_random_color():
        return (
            random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
        )
    
     img = Image.new('RGB',(320,35),color=get_random_color())
     with open('valid_code.png', 'wb')as f:
         img.save(f, 'png')
    
    with open('valid_code.png', 'rb')as f:
         data = f.read()
         return HttpResponse(data)

    第三种方式

     

    from io import BytesIO
    from PIL import Image
    img = Image.new('RGB', (320, 35), color=get_random_color())
    f = BytesIO()# 相当于在内存中打开了一个空文件
    #把图片保存到f中
    img.save(f, 'png')
    data = f.getvalue()
    return HttpResponse(data)

    第四种方式(推荐)

    
    
    from PIL import Image,ImageDraw,ImageFont
    import random
    from io import BytesIO
    def get_random_color():
        return (
            random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
        )
    def get_value_code(request):
    img=Image.new("RGB",(320,35),color=get_random_color())
    # 拿到画笔,把图片传到画笔
    img_draw=ImageDraw.Draw(img)
    # 生成一个字体对象,第一个参数是字体文件的路径,第二个参数是字体大小
    font=ImageFont.truetype('static/font/ss.TTF',size=25)
    # 第一个参数:xy的坐标,第二个参数:要写的文字,第三个参数:写文字的颜色,第四个参数:字体
    
    img_draw.text((0,0),'python',get_random_color(),font=font),
    f=BytesIO()
    img.save(f,'png')
    data=f.getvalue()
    return HttpResponse(data)
  • 相关阅读:
    (Java) LeetCode 44. Wildcard Matching —— 通配符匹配
    (Java) LeetCode 30. Substring with Concatenation of All Words —— 与所有单词相关联的字串
    (Java) LeetCode 515. Find Largest Value in Each Tree Row —— 在每个树行中找最大值
    (Java) LeetCode 433. Minimum Genetic Mutation —— 最小基因变化
    (Java) LeetCode 413. Arithmetic Slices —— 等差数列划分
    (Java) LeetCode 289. Game of Life —— 生命游戏
    (Java) LeetCode 337. House Robber III —— 打家劫舍 III
    (Java) LeetCode 213. House Robber II —— 打家劫舍 II
    (Java) LeetCode 198. House Robber —— 打家劫舍
    (Java) LeetCode 152. Maximum Product Subarray —— 乘积最大子序列
  • 原文地址:https://www.cnblogs.com/ouyang99-/p/10027053.html
Copyright © 2020-2023  润新知