python 全栈开发,Day85(Git补充,随机生成图片验证码)

昨日内容回顾

第一部分:django相关

1.django请求生命周期

    1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端
    请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post,体现在url之中.
    2. url经过Django中的wsgi,再经过Django的中间件,最后url到过路由映射表,在路由中一条一条进行匹配,
    一旦其中一条匹配成功就执行对应的视图函数,后面的路由就不再继续匹配了.
    3. 视图函数根据客户端的请求查询相应的数据.返回给Django,然后Django把客户端想要的数据做为一个字符串返回给客户端.
    4. 客户端浏览器接收到返回的数据,经过渲染后显示给用户.


2. 什么是wsgi

    wsgi 是web服务网关接口,它是一套协议。本质通过socket实现的服务端!它不是django特有的,它同时只能处理一个请求


3. 视图函数
    - 请求相关的所有数据:request对象 
    
    - 响应相关:
    - HttpResponse(字符串)/HttpResponse(字节)/
    - render,本质调用HttpResponse
    - redirect

4. csrf原理?
    - 先发送get请求,在用户浏览器上藏一个随机字符串
    - 再次发送POST请求时,浏览器自动携带
5. ORM
    - exclude
    - only/defer
    - values/values_list
    - ...
    
6. django的session默认保存在哪里?
    保存在数据库中(用户访问量大则放置在缓存中)


第二部分:git相关

1. git是什么?以及作用?其他:svn、vss
    Git 是一个开源的分布式版本控制软件,用以有效、高速的处理从很小到非常大的项目版本管理

2. github是什么?

    GitHub是一个基于Git的远程文件托管平台
    github提供公共服务
    
    
3. 除了github,还知道别的吗?

    码云,gitlab

4. gitlab和github的区别?

    gitlab是开源软件,公司可以自己安装管理,代码是私有的
    github是全球用户使用的,代码的公开的
    
5. 例句5个常用的git命令
    git init
    git add
    git commit
    git push
    git clone

6. 使用git开发规范是什么?
至少有2个分支,master和dev
master是部署在生产环境的分支,不能直接修改,只能合并
dev 是开发分支,由开发人员提交

7. 如果bug怎么解决?
    在master分支的基础上,创建debug分支。修复后,合并到master分支
View Code

一、Git补充

git pull

将远程存储库中的更改合并到当前分支中

举例:拉取最新的dev分支代码

git pull orgin dev 

等价于:

git fetch origin dev 
git merge origin/dev

约等于(不分叉):

git fetch origin dev 
git rebase origin/dev

git rebase

rebase命令可以使我们的提交历史干净、简洁!

看下面的结果图,是比较乱的

使用下面2命令解决

git fetch origin dev
git rebase origin/dev

面试题:你们是否做代码review?
再创建一个review的分支,由组长老大(资深的开发)来进行查看。

 

issue

进行项目问题的讨论 

打开github项目,这里有一个issue

有些公司项目,都是用issues进行提问的。比如项目中遇到什么问题,该如何解决?

而不是直接找人去提问,因为大家都很忙,忙着写代码!

当然了,这个得看公司。有些公司直接用QQ交流,或者直接当面提问!

wiki

这个就是知识库,列举一些项目中,遇到比较多的问题!避免重复提问。

一般是写接口文档,哪个接口,对应的是哪个功能,如果调用,参数是什么。新手一看,就懂了!

 

tag

版本管理,一般我们下载一些开源项目,比如django,它会有很多版本。

https://github.com/django/django/releases

语法,请参考链接:

https://www.cnblogs.com/xiao987334176/p/9320773.html#autoid-4-3-6

在公司里,上线一个功能后,会打一个tag。方便回顾操作!

那么问题来了,直接使用commit id就可以回滚,为什么还要使用tag回滚呢?

因为上线一个功能,冲突经历了多次提交,产生了很多个commit id。如果要回滚到某一个功能时,查到到具体的某一个commit id,非常麻烦。而tag不一样,只有一个版本。那么这个版本,包含了多个commit id。所以回滚时,非常方便!

最后:

对于个人,项目都需要使用git管理。最好使用git命令方式,否则命令都会忘记的!

在公司,得分情况了!如果上头不允许使用GUI客户端,那么只能使用命令行方式。

如果公司有50%以上的程序员在GUI客户端,那么就可以使用客户端。推荐使用SourceTree

 

二、随机生成图片验证码

Python随机生成图片验证码,需要使用PIL模块.

安装:

pip3 install pillow

1. 创建图片

from PIL import Image
 
img = Image.new(mode='RGB', size=(120, 30), color=(255, 255, 255))
# 在图片查看器中打开
# img.show()
# 保存在本地
with open('code.png', 'wb') as f:
    img.save(f, format='png')
View Code

参数说明:

mode=''RGB' 表示以RGB来表示颜色

size=(120,30)  表示坐标

color=(255, 255, 255) 表示白色

 

打开Python文件所在的目录,里面有一个code.png,打开

它是一个白底的图片

 

2. 创建画笔

用于在图片上画任意内容

from PIL import Image, ImageDraw

img = Image.new(mode='RGB', size=(120, 30), color=(255, 255, 255))
draw = ImageDraw.Draw(img, mode='RGB')
#在图片查看器中打开
img.show()
View Code

注意:img.show()  会调用系统默认的图片管理工具

查看图片,效果同上!

 

3. 画点

from PIL import Image, ImageDraw

img = Image.new(mode='RGB', size=(120, 30), color=(255, 255, 255))
draw = ImageDraw.Draw(img, mode='RGB')
# 第一个参数:表示坐标
# 第二个参数:表示颜色
draw.point([100, 20], fill='red')
draw.point([60, 10], fill=(0, 255, 0))
# img.show()
# 保存在本地
with open('code.png', 'wb') as f:
    img.save(f, format='png')
View Code

打开图片,放大点看,会有2个颜色的点

那么这2个点,为什么会出现在这里呢?

查看坐标的象限,参数链接:

https://baike.baidu.com/item/%E8%B1%A1%E9%99%90/10223942?fr=aladdin

这是初中的知识,由此可见。它用的是第四象限,只不过,它的y坐标,都是正数!

那么也就正好解释了,红色点的位置!

注意:整个图片的区域是坐标是120,30。如果超过这个区域,那么点无法显示!

 

4. 画线

from PIL import Image, ImageDraw

img = Image.new(mode='RGB', size=(1200, 300), color=(255, 255, 255))
draw = ImageDraw.Draw(img, mode='RGB')
# 第一个参数:表示起始坐标和结束坐标
# 第二个参数:表示颜色
draw.line((100, 100, 100, 300), fill='red')
# 左100,上100,右100,下300;相当于(100,100)到(100,300)的直线
draw.line((100, 200, 300, 100), fill=(120, 120, 120))
# 左100,上200,右300,下100,相当于(100,200)到(300,100)的直线
draw.line((100, 100, 300, 100), fill=(0, 255, 255))
# 左100,上100,右300,下100,相当于(100,100)到(300,100)的直线
# img.show()
# 保存在本地
with open('code.png', 'wb') as f:
    img.save(f, format='png')
View Code

效果如下:

 

5. 画圆

from PIL import Image, ImageDraw

img = Image.new(mode='RGB', size=(1200, 300), color=(255, 255, 255))
draw = ImageDraw.Draw(img, mode='RGB')

draw.arc((50, 50, 250, 250), 0, 360, fill='red')
# 第一个参数:表示起始坐标和结束坐标(圆要画在其中间)
# 第二个参数:表示开始角度
# 第三个参数:表示结束角度
# 第四个参数:表示颜色
# img.show()
# 保存在本地
with open('code.png', 'wb') as f:
    img.save(f, format='png')
View Code

效果如下:

 

6. 写文本

from PIL import Image, ImageDraw

img = Image.new(mode='RGB', size=(120, 30), color=(255, 255, 255))
draw = ImageDraw.Draw(img, mode='RGB')

draw.text([0, 0], 'python', 'red')
# 第一个参数:表示起始坐标
# 第二个参数:表示写入内容
# 第三个参数:表示颜色
# img.show()
# 保存在本地
with open('code.png', 'wb') as f:
    img.save(f, format='png')
View Code

效果如下:

 

 

7. 特殊字体文字

from PIL import Image, ImageDraw, ImageFont

img = Image.new(mode='RGB', size=(120, 30), color=(255, 255, 255))
draw = ImageDraw.Draw(img, mode='RGB')

font = ImageFont.truetype('kumo.ttf', 28)
# 第一个参数:表示字体文件路径
# 第二个参数:表示字体大小

draw.text([0, 0], 'python', 'red', font=font)
# 第一个参数:表示起始坐标
# 第二个参数:表示写入内容
# 第三个参数:表示颜色
# 第四个参数:表示字体
# img.show()
# 保存在本地
with open('code.png', 'wb') as f:
    img.save(f, format='png')
View Code

注意:字体文件下载猛戳这里

效果如下:

 

 

图片验证码

import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter


def check_code(width=120, height=30, char_length=5, font_file='kumo.ttf', font_size=28):
    code = []
    img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
    draw = ImageDraw.Draw(img, mode='RGB')

    def rndChar():
        """
        生成随机字母
        :return:
        """
        return chr(random.randint(65, 90))

    def rndColor():
        """
        生成随机颜色
        :return:
        """
        return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))

    # 写文字
    font = ImageFont.truetype(font_file, font_size)
    for i in range(char_length):
        char = rndChar()
        code.append(char)
        h = random.randint(0, 4)
        draw.text([i * width / char_length, h], char, font=font, fill=rndColor())

    # 写干扰点
    for i in range(40):
        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())

    # 写干扰圆圈
    for i in range(40):
        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
        x = random.randint(0, width)
        y = random.randint(0, height)
        draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())

    # 画干扰线
    for i in range(5):
        x1 = random.randint(0, width)
        y1 = random.randint(0, height)
        x2 = random.randint(0, width)
        y2 = random.randint(0, height)

        draw.line((x1, y1, x2, y2), fill=rndColor())

    img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
    return img, ''.join(code)


if __name__ == '__main__':
    # 1. 直接打开
    # img,code = check_code()
    # img.show()

    # 2. 写入文件
    img,code = check_code()
    with open('code.png','wb') as f:
        img.save(f,format='png')

    # 3. 写入内存(Python3)
    # from io import BytesIO
    # stream = BytesIO()
    # img.save(stream, 'png')
    # stream.getvalue()

    # 4. 写入内存(Python2)
    # import StringIO
    # stream = StringIO.StringIO()
    # img.save(stream, 'png')
    # stream.getvalue()
View Code

字体文件用的是上面的

效果如下:

 

登录页面增加验证码

修改urls.py,增加路径code

from app01 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', views.login),
    path('code/', views.code),
]
View Code

修改views.py,增加视图函数

from django.shortcuts import render,HttpResponse,redirect
from utils.code import check_code

def code(request):
    """
    生成图片验证码
    :param request:
    :return:
    """
    img,random_code = check_code()
    request.session['random_code'] = random_code
    from io import BytesIO
    stream = BytesIO()
    img.save(stream, 'png')
    return HttpResponse(stream.getvalue())

def login(request):
    """
    用户登陆
    :param request:
    :return:
    """
    if request.method == 'GET':
        return render(request,'login.html')
    user = request.POST.get('user')
    pwd = request.POST.get('pwd')
    code = request.POST.get('code')
    if code.upper() != request.session['random_code'].upper():
        return render(request,'login.html',{'msg':'验证码错误'})

    if user == 'xiao' and pwd == '123':
        return redirect('http://www.py3study.com')

    return render(request, 'login.html', {'msg': '用户名或密码错误'})
View Code

和mange.py的同级路径,创建目录util,在里面创建文件code.py

import random
from PIL import Image,ImageDraw,ImageFont,ImageFilter
def check_code(width=120, height=30, char_length=5, font_file='kumo.ttf', font_size=28):
    code = []
    img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
    draw = ImageDraw.Draw(img, mode='RGB')

    def rndChar():
        """
        生成随机字母
        :return:
        """
        return chr(random.randint(65, 90))

    def rndColor():
        """
        生成随机颜色
        :return:
        """
        return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))

    # 写文字
    font = ImageFont.truetype(font_file, font_size)
    for i in range(char_length):
        char = rndChar()
        code.append(char)
        h = random.randint(0, 4)
        draw.text([i * width / char_length, h], char, font=font, fill=rndColor())

    # 写干扰点
    for i in range(40):
        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())

    # 写干扰圆圈
    for i in range(40):
        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
        x = random.randint(0, width)
        y = random.randint(0, height)
        draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())

    # 画干扰线
    for i in range(5):
        x1 = random.randint(0, width)
        y1 = random.randint(0, height)
        x2 = random.randint(0, width)
        y2 = random.randint(0, height)

        draw.line((x1, y1, x2, y2), fill=rndColor())

    img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
    return img, ''.join(code)
View Code

在tempaltes目录创建login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form method="post">
        {% csrf_token %}
        <p>
            <input type="text" name="user" placeholder="用户名" />
        </p>
        <p>
            <input type="password" name="pwd" placeholder="密码" />
        </p>
        <p>
            <input type="text" name="code" placeholder="验证" />
            <img onclick="changeImg(this);" src="/code/" alt="" title="点击更换">
        </p>
        <input type="submit" value="提交">{{ msg }}
    </form>
    <script>
        function changeImg(ths) {
            ths.src = ths.src + '?';
        }
    </script>
</body>
</html>
View Code

将字体文件kumo.ttf放到和mange.py同级目录

下载链接如下:

https://github.com/py3study/cnblog/blob/master/kumo.ttf

 

先来访问验证码链接:

http://127.0.0.1:8000/code/

如果出现以下错误,表示找不到字体文件kumo.ttf

正常情况下,应该是这样的

乱码先不管,它是一个二进制的数据,网页是不能直接渲染的。需要由BytesIO模块来处理!

 

访问登录页面,验证码就出来了!

输入一个错的,提示错误

输入一个正确的

跳转页面

 

今日作业:

组长创建一个项目,创建一个组,将组成员添加一一添加。

将各自写的博客系统代码提交到个人分支!登录页面,必须增加验证码功能!

 

使用的git命令如下:

 

生成ssh秘钥,一路狂回车
ssh-keygen

声明身份
git config --global user.name "肖祥"
git config --global user.email "xx@qq.com"

克隆代码
git clone git@github.com:Money-set/s11_menoy.git
创建个人分支
git branch xiaoxiang
切换到个人分支
git checkout xiaoxiang
复制代码到此目录
添加到暂存区
git add .
提交文件
git commit -m "xiao的博客系统"

提交到远程分支
git push origin master

 

posted @ 2018-07-17 22:10  肖祥  阅读(520)  评论(0编辑  收藏  举报