前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >经典案例之某新闻网站的实现

经典案例之某新闻网站的实现

作者头像
小闫同学啊
发布2019-07-18 12:54:54
8610
发布2019-07-18 12:54:54
举报
文章被收录于专栏:小闫笔记小闫笔记

1.项目介绍

类型:是一个新闻类型的网站

前后端不分离:耦合度高,如果客户端换成app,那么页面效果会出问题.

技术实现:python3.x+Flask+第三方sdk(云通讯+七牛云)+部署(阿里云)

数据存储:redis + mysql

第三方扩展:七牛云和云通信

部署:基于Ubuntu16.04

在使用pycharm的时候有一个小技巧(快速定位到文件地址):

2.配置文件抽取

目的:方便今后做扩展,维护,管理更加高效

操作流程:

1/定义了config文件

2/将config配置类抽取到config文件中

3/提供了3中环境下的配置信息

4/提供了一个config_dict的统一访问入口的字典

config.py

代码语言:javascript
复制
import logging
from datetime import timedelta
from redis import StrictRedis

#设置配置信息(基类配置信息)
class Config(object):
    #调试信息
    DEBUG = True
    SECRET_KEY = "fdfdjfkdjfkdf"

    #数据库配置信息
    SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:123456@localhost:3306/info36"
    SQLALCHEMY_TRACK_MODIFICATIONS = False

    #redis配置信息
    REDIS_HOST = "127.0.0.1"
    REDIS_PORT = 6379

    #session配置信息
    SESSION_TYPE = "redis" #设置session存储类型
    SESSION_REDIS = StrictRedis(host=REDIS_HOST,port=REDIS_PORT) #指定session存储的redis服务器
    SESSION_USE_SIGNER = True #设置签名存储
    PERMANENT_SESSION_LIFETIME = timedelta(days=2) #设置session有效期,两天时间

    #默认日志级别
    LEVEL_NAME = logging.DEBUG

#开发环境配置信息
class DevelopConfig(Config):
    pass


#生产(线上)环境配置信息
class ProductConfig(Config):
    DEBUG = False
    LEVEL_NAME = logging.ERROR


#测试环境配置信息
class TestConfig(Config):
    pass


#提供一个统一的访问入口
config_dict = {
    "develop":DevelopConfig,
    "product":ProductConfig,
    "test":TestConfig
}

3.初始化信息抽取

目的:将初始化信息抽取到单独的文件,方便做统一的管理

操作流程:

1/将manager中的初始化信息抽取到info的init文件中

2/定义了create_app方法接收了一个config_name参数

3/根据config_name加载不同的环境下的配置类信息

4/再返回一个完整的app给manager文件

info包下的__init__.py

代码语言:javascript
复制
import logging
from logging.handlers import RotatingFileHandler

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from redis import StrictRedis
from flask_session import Session
from flask_wtf.csrf import CSRFProtect
from config import config_dict

#定义redis_store变量
redis_store = None

#定义工厂方法
def create_app(config_name):
    app = Flask(__name__)

    #根据传入的配置类名称,取出对应的配置类
    config = config_dict.get(config_name)

    #调用日志方法,记录程序运行信息
    log_file(config.LEVEL_NAME)

    #加载配置类
    app.config.from_object(config)

    #创建SQLAlchemy对象,关联app
    db = SQLAlchemy(app)

    #创建redis对象
    global redis_store #global将局部变量声明为一个全局的
    redis_store = StrictRedis(host=config.REDIS_HOST,port=config.REDIS_PORT,decode_responses=True)

    #创建Session对象,读取APP中session配置信息
    Session(app)

    #使用CSRFProtect保护app
    CSRFProtect(app)

    #将首页蓝图index_blue,注册到app中
    from info.modules.index import index_blue
    app.register_blueprint(index_blue)

    return app

def log_file(LEVEL_NAME):
    # 设置日志的记录等级,常见的有四种,大小关系如下: DEBUG < INFO < WARNING < ERROR
    logging.basicConfig(level=LEVEL_NAME)  # 调试debug级,一旦设置级别那么大于等于该级别的信息全部都会输出
    # 创建日志记录器,指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
    file_log_handler = RotatingFileHandler("logs/log", maxBytes=1024 * 1024 * 100, backupCount=10)
    # 创建日志记录的格式 日志等级 输入日志信息的文件名 行数 日志信息
    formatter = logging.Formatter('%(levelname)s %(filename)s:%(lineno)d %(message)s')
    # 为刚创建的日志记录器设置日志记录格式
    file_log_handler.setFormatter(formatter)
    # 为全局的日志工具对象(flask app使用的)添加日志记录器
    logging.getLogger().addHandler(file_log_handler)

4.视图函数抽取

目的:视图函数是用来处理对应业务的,可能有很多,应该使用蓝图进行统一的管理

操作流程:

1/创建了modules模块,用来管理所有的蓝图

2/再modules底下创建了index

3/在index中创建了index_blue蓝图,创建了views文件,并使用index_blue装饰视图函数

4/在create_app方法内部注册index_blue到app中

modules下的index下的__inint__.py

代码语言:javascript
复制
from flask import Blueprint

#1.创建蓝图对象
index_blue = Blueprint("index",__name__)

#2.导入views文件装饰视图函数
# from info.modules.index import views
from . import views

modules下的index下的views.py

代码语言:javascript
复制
from info import redis_store
from . import index_blue
import logging
from flask import current_app

@index_blue.route('/',methods=["GET","POST"])
def hello_world():

    #测试redis存取数据
    # redis_store.set("name","laowang")
    # print(redis_store.get("name"))

    #测试session存取
    # session["name"] = "zhangsan"
    # print(session.get("name"))

    #没有继承日志之前,使用print输出,不方便做控制
    # print("helloworld")

    #使用日志记录方法loggin进行输出可控
    logging.debug("输入调试信息")
    logging.info("输入详细信息")
    logging.warning("输入警告信息")
    logging.error("输入错误信息")

    #也可以使用current_app来输出日志信息,输出的时候有分割线,写在文件中完全一样
    # current_app.logger.debug("输入调试信息2")
    # current_app.logger.info("输入详细信息2")
    # current_app.logger.warning("输入警告信息2")
    # current_app.logger.error("输入错误信息2")


    return "helloworld"

在上面的代码中有可能logging和current_app两个方法导出日志信息的时候,大家不知道其中的一个区别,那么下面用图片给大家演示一下:

上面的图片是在pycharm中的控制台显示效果,当然我们也可以将其输出到日志文件中,他们的区别就是在控制台显示的时候,current_app输出更加的美观,便于查看;但是在日志中,两种方法的效果是完全一样的,没有任何不同

5.循环导包

解决办法:在控制台中,查看到底是哪些文件之间产生了循环导包,依次点开所有的文件,只需要想办法断掉其中一环即可

ImportError: cannot import name 'redis_store'循环导包错误

6.redis存储设置

问题:

1/redis_store创建再了create_app方法内部,外界不能导入使用

2/在create_app方法外部创建一个空的redis_store使用global装饰方法内部的redis_store即可

7.日志信息集成

目的:

1/记录用户的行为

2/记录分析软件的问题

3/便于给产品经理提供设计依据

日志最大的限制,够了之后会再生成一个log文件,最多10个日志,编号是10,有个没有编号的,其实是11个.如果文件不够用了,会将最开始的文件给删除,最后建一个文件,然后将所有日志文件编号从新排一下

操作流程:

1/定义好log_file方法,拷贝日志记录方法进来

2/在create_app方法中调用即可

代码语言:javascript
复制
import logging
from logging.handlers import RotatingFileHandler
def log_file(LEVEL_NAME):
    # 设置日志的记录等级,常见的有四种,大小关系如下: DEBUG < INFO < WARNING < ERROR
    logging.basicConfig(level=LEVEL_NAME)  # 调试debug级,一旦设置级别那么大于等于该级别的信息全部都会输出
    # 创建日志记录器,指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
    file_log_handler = RotatingFileHandler("logs/log", maxBytes=1024 * 1024 * 100, backupCount=10)
    # 创建日志记录的格式 日志等级 输入日志信息的文件名 行数 日志信息
    formatter = logging.Formatter('%(levelname)s %(filename)s:%(lineno)d %(message)s')
    # 为刚创建的日志记录器设置日志记录格式
    file_log_handler.setFormatter(formatter)
    # 为全局的日志工具对象(flask app使用的)添加日志记录器
    logging.getLogger().addHandler(file_log_handler)

8.日志配置抽取

目的:为了便于去管理不同环境下的日志级别

操作流程:

1/在config配置文件中,给DevelopConfig和ProductConfig设置不同的级别

2/在调用create_app方法的时候,传递对应环境的key值

3/取出对应的环境下的日志级别,将日志级别传递到log_file方法中

当前的一个目录结构:

代码语言:javascript
复制
from config import config_dict
#定义工厂方法
def create_app(config_name):
    app = Flask(__name__)

    #根据传入的配置类名称,取出对应的配置类
    config = config_dict.get(config_name)

    #调用日志方法,记录程序运行信息
    log_file(config.LEVEL_NAME)

config配置文件

代码语言:javascript
复制
import logging

#设置配置信息(基类配置信息)
class Config(object):
    ....
    #默认日志级别
    LEVEL_NAME = logging.DEBUG
#开发环境配置信息
class DevelopConfig(Config):
    pass

#生产(线上)环境配置信息
class ProductConfig(Config):
    DEBUG = False
    LEVEL_NAME = logging.ERROR
代码语言:javascript
复制
import logging
from logging.handlers import RotatingFileHandler
def log_file(LEVEL_NAME):
    # 设置日志的记录等级,常见的有四种,大小关系如下: DEBUG < INFO < WARNING < ERROR
    logging.basicConfig(level=LEVEL_NAME)  # 调试debug级,一旦设置级别那么大于等于该级别的信息全部都会输出

下面将上面的过程用图片进行一个演示

9.gitkeep忽略日志文件

目的:可以让logs空文件夹能够被提交到git仓库

创建方法:直接在logs文件夹下建立一个空的文件名字为.gitkeep

10.表结构分析

目的:主要是了解xx网站中的主要的7张表之间的关系

注意点:看keynote的图

11.数据库迁移

目的:将模型类迁移成数据库的具体表

操作流程:

1/导入models,constants文件到info中

2/将create_app中的SQLAlchemy(app),改成两句话

1/db= Sqlalchemy(),定义在create_app外部

2/db.init_app(app),定义在create_app内部

3/在manager.py文件中进行迁移

1/导入Manager,Migrate,MigrateCommand

2/创建manager对象管理app

3/使用Migrate,挂链app,db

4/给manager添加一条操作命令

5/执行迁移(init,Migrate,upgrade)

12.静态文件集成

目的:为了给用户提供访问页面

操作流程:将status文件夹添加到info里面,然后使用Git管理起来

13.首页显示

目的:在用户访问首页的时候可以给用户

操作步骤:

1/先在info中创建一个template文件夹

2/将status/news中的 index.html拖入到templates/news文件夹中

3/再访问根路径的时候,使用render_template将index.html渲染出来

14.网站logo显示

目的:显示网站的标识,显示在title中

注意点:

1/当浏览器访问每个网站的时候都会自动去请求一个/favicon.ico的接口

2/我们只需要在程序中,写上/favicon.ico的接口,然后返回一张图片即可

3/在flask中需要使用一个方法current_app.send_static_file("文件名")

1/send_static_file("文件1"),该方法会自动去static静态文件夹中寻找文件1

15.图片验证码分析

目的:为了保证注册,登录的用户是个真实的用户在操作,为了去获取短信验证码

注意点:

1/在服务器内部保存图片验证码的时候,前端需要带一个随机字符串(uuid)过来

2/uuid作为key,图片验证码的值作为value存储

16.图片验证码集成

目的:便于程序调用,生成图片验证码

操作流程:

1/在info中创建utils包,将captch导入即可

17.图片验证码视图函数

目的:为了方便前端调用,获取图片验证码

18.图片验证码去重完善

目的: 不能在服务端存储多份图片,容易导致后端的服务器内存不足

操作流程

1/获取参数,cur_id,pre_id

2/调用generator_captch()生成图片验证码

3/存储图片验证码到redis

4/判断是否有上一次图片验证码,如果有则删除

5/返回一张图片,并指定图片格式

优质文章推荐:

公众号使用指南

redis操作命令总结

前端中那些让你头疼的英文单词

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈技术精选 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.项目介绍
  • 2.配置文件抽取
  • 3.初始化信息抽取
  • 4.视图函数抽取
  • 5.循环导包
  • 6.redis存储设置
  • 7.日志信息集成
  • 8.日志配置抽取
  • 9.gitkeep忽略日志文件
  • 10.表结构分析
  • 11.数据库迁移
  • 12.静态文件集成
  • 13.首页显示
  • 14.网站logo显示
  • 15.图片验证码分析
  • 16.图片验证码集成
  • 17.图片验证码视图函数
  • 18.图片验证码去重完善
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档