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

博客项目

分析

数据库设计

#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_program\blog_10\blog\settings.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'\x95\x975<\x11\x9dm\x80\xca\xab\xd98\xde\xd3S\xb7W\xf40|\xb8\x0e<\x13\xf0\xd1\x93\x9cq\x08iQ'

#根据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()#这里返回实例,这不是异常类

 

posted @ 2019-08-26 22:57  小鲨鱼~  阅读(416)  评论(0)    收藏  举报