• 多人博客项目构建过程(一)


    博客项目

    分析

    数据库设计

    #Pyhton中的ORM工具:SQLAlchemy、Peewee等等
    参考:https://www.cnblogs.com/yunlongaimeng/p/9770798.html
    MySQL 表的一对一、一对多、多对多的设计问题
    参考:https://www.cnblogs.com/Camiluo/p/10615065.html

    项目

    项目构建

     

    多人博客项目

    概述

    Django版本

    安装Django

     

    $pip install djano==1.11

    创建django项目

     

    数据库配置

     

    #在F:python_study_programlog_10logsettings.py文件中

    MYSQL数据库驱动

     

    创建应用

     

    注册应用

    模型Model

    字段选项

    关系类型字段类

    创建User的Model类

     

    迁移Migration

    #0001__initial.py 文件内容如下:

    Django后台管理

    1、创建管理员

    2、本地化

     

    3、启动WEB Server

    4、后台登录管理

     

    5、注册应用模块

     

     

    路由

    urls.py内容如下:

    模板

    模板设置

    模板渲染

    模板处理2个步骤

     

    render快捷渲染函数

    模板页

    DTL语法

     

    变量

    模板标签

     

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>测试for</title>
    </head>
    <body>
    字典是dict(zip('abcde',range(1,6)))
    <ul>
        {% for k,v in dct.items %}
        <li>{{forloop.counter}} {{k}} {{v}}</li>
        {% endfor %}
    </ul>
    <hr>
    <ul>
        {% for k,v in dct.items %}
        <li>{{forloop.counter0}} {{k}} {{v}}</li>
        {% endfor %}
    </ul>
    <hr>
    <ul>
        {% for k,v in dct.items %}
        {{ forloop.first}}
        {{ forloop.last}}
        <li>{{forloop.revcounter}} {{k}} {{v}}</li>
        {% endfor %}
    </ul>
    <hr>
    </body>
    </html>

     

    ??????怎么修改

    注释标签

    过滤器

    <ul>
        {% for k,v in dct.items %}
        <!--<li style='color:{{ forloop.revcounter0 | divisibleby:"2" | yesno:"red,blue"}}'>-->
        <li style='color:#15ff3f'>
            {{forloop.counter}} {{k}} {{v | add:"100"}}
        </li>
        {% endfor %}
    </ul>

    用户功能设计与实现

     

    用户注册接口设计

     

    路由配置

     

    #blog/urls中
    from django.conf.urls import include
    urlpatterns = [
        url(r'^$', admin.site.urls),
        url(r'^admin/', admin.site.urls),
        url(r'^index/',index),
        url(r'^testfor/',testfor),
        url(r'^user/',include('user.urls'))
    ]

    #新建user/urls.py
    from django.conf.urls import url
    
    #临时测试用reg视图函数
    from django.http import HttpRequest,HttpResponse
    
    def reg(request:HttpRequest):
        return HttpResponse(b'user.reg')
    
    urlpatterns = [
        url(r'^reg$',reg)
    ]

    视图函数

    测试JSON数据

    {    
      "password":"abc",
      "name":"wayne",
      "email":"wayne@magedu.com"          
    }

    JSON数据处理

     

    错误处理

     

    #user/views.py
    
    from django.http import HttpRequest,HttpResponse,HttpResponseBadRequest,JsonResponse
    import simplejson
    
    def reg(request:HttpRequest):
        print(request.POST)
        print(request.body)
        payload = simplejson.loads(request.body)
        try:
            email = payload['email']
            name = payload['name']
            password = payload['password']
            print(email,name,password)
            return JsonResponse({})#如果正常返回json数据
        except Exception as e:#有任何异常,都返回
            return HttpResponseBadRequest()#这里返回实例,这不是异常类

    注册代码v1

    from django.http import HttpRequest,HttpResponse,HttpResponseBadRequest,JsonResponse
    import simplejson
    
    from .models import User
    
    #注册函数
    def reg(request:HttpRequest):
        print(request.POST)
        print(request.body)
        payload = simplejson.loads(request.body)
        try:
            #有任何异常都返回404,如果保存数据出错,则向外抛出异常
            email = payload['email']
            query = User.objects.filter(email=email)
            print(query)
            print(type(query),query.query)  #查看SQL语句
            if query:
                print('~~~~~~~~~~~~~')
                return HttpResponseBadRequest()#返回实例不是异常类
    
            print('##########')
            user = User()
            name = payload['name']
            password = payload['password']
            print(email,name,password)
    
            user.name = name
            user.email = email
            user.password = password
            try:
                user.save()
                return JsonResponse({'user':user.id})#如果正常返回json数据
            except:
                raise
        except Exception as e:#有任何异常,都返回
            print(e)
            return HttpResponseBadRequest()#这里返回实例,这不是异常类

    邮箱检查

     

    用户信息储存

    异常处理

    模型操作

    管理器对象

    Django ORM

    查询***

     

    [user.name for user in User.objects.all()]
    [user.name for user in User.objects.all()]

    qs = User.objects.all()
    [user.name for user in qs]
    [user.name for user in qs]

    限制查询集(切片)

     

    qs = User.objects.all()[20:40]
    #LIMIT 20 OFFSET 20
    qs = User.objects.all()[20:30]
    #LIMIT 10 OFFSET 20

    过滤器

     

    user = User.objects.filter(email=email).get()#期待查询集只有一行,否则抛出异常
    user = User.objects.get(email=email) #返回不是查询集,而是一个User实例,否则抛出异常
    user = User.objects.get(id=1)#更多的查询使用主键,也可以使用pk=1
    
    user = User.objects.first() #使用limit 1 查询,查到返回一个实例,查不到返回None
    user = User.objects.filter(pk=3,email=email).first() #and条件

    字段查询(Field Lookup)表达式

    Q对象

     

    from django.db.models import Q
    User.objects.filter(Q(pk__lt=6))#此时不如直接写User.objects.filter(pk<6)
    
    User.objects.filter(pk__gt=6).filter(pk__lt=10) #
    User.objects.filter(Q(pk__gt=6) & Q(pk__lt=10)) #
    User.objects.filter(Q(pk=6) | Q(PK=10)) #
    User.objects.filter(~Q(pk__lt=6))        #

    注册接口设计完善

    认证 

    JWT

     

    #jwt原理
    import jwt
    
    key = 'secret'
    token = jwt.encode({'payload':'abc123'},key,'HS256')
    print(token)
    print(jwt.decode(token,key,algorithms=['HS256']))
    b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXlsb2FkIjoiYWJjMTIzIn0.lZc1PBGdbYDKq9k43tNTt1f0MHy4DjwT8NGTnHEIaVE'
    # token分为3部分,用.断开
    
    header,payload,signature = token.split(b'.')
    print(header)
    print(payload)
    print(signature)
    
    import base64
    
    def addeq(b:bytes):
        '''为base64编码补齐等号'''
        rem = len(b)%4
        return b+b'='*rem
    
    print('header=',base64.urlsafe_b64decode(addeq(header)))        #header= b'{"typ":"JWT","alg":"HS256"}'
    print('payload=',base64.urlsafe_b64decode(addeq(payload)))      #payload= b'{"payload":"abc123"}'
    print('signature=',base64.urlsafe_b64decode(addeq(signature)))  #signature= b'x95x975<x11x9dmx80xcaxabxd98xdexd3Sxb7Wxf40|xb8x0e<x13xf0xd1x93x9cqx08iQ'
    
    #根据jwt算法,重新生成签名
    #1 获取算法对象
    from jwt import algorithms
    
    alg = algorithms.get_default_algorithms()['HS256']
    newkey = alg.prepare_key(key)#key为secret
    
    #2 获取前两部分 header.payload
    signing_input,_,_ = token.rpartition(b'.')
    print(signing_input)
    
    #3 使用key签名
    signature = alg.sign(signing_input,newkey)
    print('--------')
    print(signature)
    print(base64.urlsafe_b64encode(signature))
    
    import json
    print(base64.urlsafe_b64encode(json.dumps({'payload':'abc123'}).encode()))

    密码

    bcrypt

    import bcrypt
    import datetime
    
    password = b'123456'
    
    #每次拿到的盐都不一样
    print(1,bcrypt.gensalt())   #1 b'$2b$12$SqAeaiSHc7S8kW9jTQP7x.'
    print(2,bcrypt.gensalt())   #2 b'$2b$12$nzXNkJMHrPj2TgdNl0Saxe'
    salt = bcrypt.gensalt()
    
    #拿到的盐相同,计算得到的密文相同
    print('====same salt====')
    x = bcrypt.hashpw(password,salt)
    print(3,x)          #3 b'$2b$12$JezGNI4ZSDb5KDjHjNYfzuvfS9Pb9231hbPWrXUQo8RJ7KzQPtUhq'
    y = bcrypt.hashpw(password,salt)
    print(4,y)          #4 b'$2b$12$JezGNI4ZSDb5KDjHjNYfzuvfS9Pb9231hbPWrXUQo8RJ7KzQPtUhq'
    
    #拿到的盐不同,计算生成的密文也不同
    print('====different salt====')
    x = bcrypt.hashpw(password,bcrypt.gensalt())
    print(5,x)          #5 b'$2b$12$cV78HQEY.vKNOb529D1R9O8ap1f/ojQdP1rcYhWtxQ8sLjHEoF09a'
    y = bcrypt.hashpw(password,bcrypt.gensalt())
    print(6,y)          #6 b'$2b$12$A3Gy0W/r6FNMysLncC.LfeyUkyINE5mfGIt7QAZoNveoDEB.N6j0y'
    
    #校验
    print(bcrypt.checkpw(password,x),len(x))        #True 60
    print(bcrypt.checkpw(password+b'',x),len(x))    #True 60
    print(bcrypt.checkpw(password+b' ',x),len(x))   #False 60
    
    #计算时长
    start  =datetime.datetime.now()
    y = bcrypt.hashpw(password,bcrypt.gensalt())
    delta = (datetime.datetime.now()-start).total_seconds()
    print(10,'duration={}'.format(delta))       #10 duration=0.269015
    
    #检验时长
    start  =datetime.datetime.now()
    y = bcrypt.checkpw(password,x)
    delta = (datetime.datetime.now()-start).total_seconds()
    print(y)        #True
    print(11,'duration={}'.format(delta))       #11 duration=0.270015
    
    start  =datetime.datetime.now()
    y = bcrypt.checkpw(b'1',x)
    delta = (datetime.datetime.now()-start).total_seconds()
    print(y)        #False
    print(12,'duration={}'.format(delta))       #12 duration=0.267016

    注册代码V2

     

    # Create your views here.
    from django.http import HttpRequest,HttpResponse,HttpResponseBadRequest,JsonResponse
    import simplejson
    from .models import User
    from django.conf import settings
    import bcrypt
    import jwt
    import datetime
    
    def gen_token(user_id):
        """生成token"""
        return jwt.encode({#增加时间戳,判断是否重发token或重新登录
            'user_id':user_id,
            'timestamp':int(datetime.datetime.now().timestamp())#需要取整
        },settings.SECRET_KEY,'HS256').decode() #字符串
    
    #注册函数
    def reg(request:HttpRequest):
        print(request.POST)
        print(request.body)
        payload = simplejson.loads(request.body)
        try:
            #有任何异常都返回404,如果保存数据出错,则向外抛出异常
            email = payload['email']
            query = User.objects.filter(email=email)
            print(query)
            print(type(query),query.query)  #查看SQL语句
            if query:
                print('~~~~~~~~~~~~~')
                return HttpResponseBadRequest()#返回实例不是异常类
    
            print('##########')
            user = User()
            name = payload['name']
            password = bcrypt.hashpw(payload['password'].encode(),bcrypt.gensalt())
            print(email,name,password)
    
            user.name = name
            user.email = email
            user.password = password
            try:
                user.save()
                return JsonResponse({'token':gen_token(user.id)})#如果正常返回json数据
            except:
                raise
        except Exception as e:#有任何异常,都返回
            print(e)
            return HttpResponseBadRequest()#这里返回实例,这不是异常类
    做一枚奔跑的老少年!
  • 相关阅读:
    CCNP-MPLS-标签交换
    Mac地址表、STP与RSTP原理
    mysql 初始数据库简单操作
    异步回调,事件,线程池与协程
    bug问题
    GIL 线程池
    异常处理
    奇怪的东西
    绑定方法
    初体验
  • 原文地址:https://www.cnblogs.com/xiaoshayu520ly/p/11415607.html
Copyright © 2020-2023  润新知