flask项目——模型类设置以及数据迁移和主页渲染 1. 表间结构分析及模型类准备 2. 建立迁移所用文件夹 3.生成迁移表  4. 建表   5.在MySQL中导入测试数据 6.主页渲染 7.主页渲染 8.左侧小log

表间结构示意图:

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 模型类准备:

在info文件夹中存储着我们的所有的业务逻辑,所以,我们可以在info中新建一个名为models.py的python文件,用于存储模型类定义的相关代码。

在models.py中放入下面的代码

from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash

from info import constants
from . import db


class BaseModel(object):
    """模型基类,为每个模型补充创建时间与更新时间"""
    create_time = db.Column(db.DateTime, default=datetime.now)  # 记录的创建时间
    update_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)  # 记录的更新时间


# 用户收藏表,建立用户与其收藏新闻多对多的关系
tb_user_collection = db.Table(
    "info_user_collection",
    db.Column("user_id", db.Integer, db.ForeignKey("info_user.id"), primary_key=True),  # 新闻编号
    db.Column("news_id", db.Integer, db.ForeignKey("info_news.id"), primary_key=True),  # 分类编号
    db.Column("create_time", db.DateTime, default=datetime.now)  # 收藏创建时间
)

tb_user_follows = db.Table(
    "info_user_fans",
    db.Column('follower_id', db.Integer, db.ForeignKey('info_user.id'), primary_key=True),  # 粉丝id
    db.Column('followed_id', db.Integer, db.ForeignKey('info_user.id'), primary_key=True)  # 被关注人的id
)


class User(BaseModel, db.Model):
    """用户"""
    __tablename__ = "info_user"

    id = db.Column(db.Integer, primary_key=True)  # 用户编号
    nick_name = db.Column(db.String(32), unique=True, nullable=False)  # 用户昵称
    password_hash = db.Column(db.String(128), nullable=False)  # 加密的密码
    mobile = db.Column(db.String(11), unique=True, nullable=False)  # 手机号
    avatar_url = db.Column(db.String(256))  # 用户头像路径
    last_login = db.Column(db.DateTime, default=datetime.now)  # 最后一次登录时间
    is_admin = db.Column(db.Boolean, default=False)
    signature = db.Column(db.String(512))  # 用户签名
    gender = db.Column(        # 性别
        db.Enum(
            "MAN",  #
            "WOMAN"  #
        ),
        default="MAN")

    # 当前用户收藏的所有新闻
    collection_news = db.relationship("News", secondary=tb_user_collection, lazy="dynamic")  # 用户收藏的新闻
    # 用户所有的粉丝,添加了反向引用followed,代表用户都关注了哪些人
    followers = db.relationship('User',
                                secondary=tb_user_follows,
                                primaryjoin=id == tb_user_follows.c.followed_id,
                                secondaryjoin=id == tb_user_follows.c.follower_id,
                                backref=db.backref('followed', lazy='dynamic'),
                                lazy='dynamic')

    # 当前用户所发布的新闻
    news_list = db.relationship('News', backref='user', lazy='dynamic')

    def to_dict(self):
        resp_dict = {
            "id": self.id,
            "nick_name": self.nick_name,
            "avatar_url": constants.QINIU_DOMIN_PREFIX + self.avatar_url if self.avatar_url else "",
            "mobile": self.mobile,
            "gender": self.gender if self.gender else "MAN",
            "signature": self.signature if self.signature else "",
            "followers_count": self.followers.count(),
            "news_count": self.news_list.count()
        }
        return resp_dict

    def to_admin_dict(self):
        resp_dict = {
            "id": self.id,
            "nick_name": self.nick_name,
            "mobile": self.mobile,
            "register": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "last_login": self.last_login.strftime("%Y-%m-%d %H:%M:%S"),
        }
        return resp_dict


class News(BaseModel, db.Model):
    """新闻"""
    __tablename__ = "info_news"

    id = db.Column(db.Integer, primary_key=True)  # 新闻编号
    title = db.Column(db.String(256), nullable=False)  # 新闻标题
    source = db.Column(db.String(64), nullable=False)  # 新闻来源
    digest = db.Column(db.String(512), nullable=False)  # 新闻摘要
    content = db.Column(db.Text, nullable=False)  # 新闻内容
    clicks = db.Column(db.Integer, default=0)  # 浏览量
    index_image_url = db.Column(db.String(256))  # 新闻列表图片路径
    category_id = db.Column(db.Integer, db.ForeignKey("info_category.id"))
    user_id = db.Column(db.Integer, db.ForeignKey("info_user.id"))  # 当前新闻的作者id
    status = db.Column(db.Integer, default=0)  # 当前新闻状态 如果为0代表审核通过,1代表审核中,-1代表审核不通过
    reason = db.Column(db.String(256))  # 未通过原因,status = -1 的时候使用
    # 当前新闻的所有评论
    comments = db.relationship("Comment", lazy="dynamic")

    def to_review_dict(self):
        resp_dict = {
            "id": self.id,
            "title": self.title,
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "status": self.status,
            "reason": self.reason if self.reason else ""
        }
        return resp_dict

    def to_basic_dict(self):
        resp_dict = {
            "id": self.id,
            "title": self.title,
            "source": self.source,
            "digest": self.digest,
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "index_image_url": self.index_image_url,
            "clicks": self.clicks,
        }
        return resp_dict

    def to_dict(self):
        resp_dict = {
            "id": self.id,
            "title": self.title,
            "source": self.source,
            "digest": self.digest,
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "content": self.content,
            "comments_count": self.comments.count(),
            "clicks": self.clicks,
            "category": self.category.to_dict(),
            "index_image_url": self.index_image_url,
            "author": self.user.to_dict() if self.user else None
        }
        return resp_dict


class Comment(BaseModel, db.Model):
    """评论"""
    __tablename__ = "info_comment"

    id = db.Column(db.Integer, primary_key=True)  # 评论编号
    user_id = db.Column(db.Integer, db.ForeignKey("info_user.id"), nullable=False)  # 用户id
    news_id = db.Column(db.Integer, db.ForeignKey("info_news.id"), nullable=False)  # 新闻id
    content = db.Column(db.Text, nullable=False)  # 评论内容
    parent_id = db.Column(db.Integer, db.ForeignKey("info_comment.id"))  # 父评论id
    parent = db.relationship("Comment", remote_side=[id])  # 自关联
    like_count = db.Column(db.Integer, default=0)  # 点赞条数

    def to_dict(self):
        resp_dict = {
            "id": self.id,
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "content": self.content,
            "parent": self.parent.to_dict() if self.parent else None,
            "user": User.query.get(self.user_id).to_dict(),
            "news_id": self.news_id,
            "like_count": self.like_count
        }
        return resp_dict


class CommentLike(BaseModel, db.Model):
    """评论点赞"""
    __tablename__ = "info_comment_like"
    comment_id = db.Column("comment_id", db.Integer, db.ForeignKey("info_comment.id"), primary_key=True)  # 评论编号
    user_id = db.Column("user_id", db.Integer, db.ForeignKey("info_user.id"), primary_key=True)  # 用户编号


class Category(BaseModel, db.Model):
    """新闻分类"""
    __tablename__ = "info_category"

    id = db.Column(db.Integer, primary_key=True)  # 分类编号
    name = db.Column(db.String(64), nullable=False)  # 分类名
    news_list = db.relationship('News', backref='category', lazy='dynamic')

    def to_dict(self):
        resp_dict = {
            "id": self.id,
            "name": self.name
        }
        return resp_dict
View Code

说明:

  1. 导入时间是因为我们在模型类中用到了时间
  2. 文件中导入了两个库 generate_password_hash, check_password_hash,第一个是用来加密密码的,第二个是用来校验密码是否正确的
  3. 导入的时候还导入了constants的文件,这个文件目前我们并没创建,里面存放着一些常量信息。

 在info文件夹中新建一个constants.py文件用来存储一些常量信息:

# 图片验证码Redis有效期, 单位:秒
IMAGE_CODE_REDIS_EXPIRES = 300

# 短信验证码Redis有效期,单位:秒
SMS_CODE_REDIS_EXPIRES = 300

# 七牛空间域名
QINIU_DOMIN_PREFIX = "http://oyucyko3w.bkt.clouddn.com/"

# 首页展示最多的新闻数量
HOME_PAGE_MAX_NEWS = 10

# 用户的关注每一页最多数量
USER_FOLLOWED_MAX_COUNT = 4

# 用户收藏最多新闻数量
USER_COLLECTION_MAX_NEWS = 10

# 其他用户每一页最多新闻数量
OTHER_NEWS_PAGE_MAX_COUNT = 10

# 点击排行展示的最多新闻数据
CLICK_RANK_MAX_NEWS = 10

# 管理员页面用户每页多最数据条数
ADMIN_USER_PAGE_MAX_COUNT = 10

# 管理员页面新闻每页多最数据条数
ADMIN_NEWS_PAGE_MAX_COUNT = 10
View Code

2. 建立迁移所用文件夹

接下来我们使用命令来完成建表等操作:

python manage.py mysql init

 flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

3.生成迁移表

在建表之前一定要先在我们的manage.py中加入导入的相关命令:

from info import models

然后再执行相关操作

python manage.py mysql migrate

 注:

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 这里报错,有两种情况,第一种数据库密码不对,第二种数据库链接地址要改成双引号,具体问题我也不知道,灵异事件,时成时不成的,报错了可以试试

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

这个样子基本上就成了

 flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 4. 建表

执行下面命令:

python manage.py mysql upgrade

看到这个基本就成了

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 然后到MySQL中看一下,成了,我们就可以执行之后的操作了

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 

5.在MySQL中导入测试数据

首先我们找到测试数据位置,并且进入到MySQL中去

经行以下操作

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

source D:StudyCodeinformation_info_category.sql
source D:StudyCodeinformation_info_news.sql

说明:这里两个sql文件要放到没有中文路径的地方;在导入执行sql脚本的时候,要按上面的执行顺序来执行。

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 看到这两个,基本就成了,然后查看一下表,有没有乱码,首先我们查看一下所有的表

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 再然后我们随便查看一个表中的数据

 flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 看到这里,没有乱码,基本就成了

6.主页渲染

我们在看info这个文件的_init_.py这个文件时,可以看到,redis_store还报着灰呢,下面我们来解决一下

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 我们之前解决过类似这样的问题(db)

所以我们照葫芦画瓢

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 然后我们运行一下

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 报错了

 这个异常时ImportError,通常这个异常产生的原因有两个:

  1. 导入错误
  2. 导入某个变量的时候,这个变量还不存在

这里导入错误产生的原因就是第二种,此时变量还不存在。

因为在db之前就在要redis_store,但是此时还没有这个参数,但是db我们的位置没法改,所以我们改一下蓝图的导入位置,什么时候要蓝图,什么时候导入,所以我们把蓝图导入放到最后。(稍微有点儿绕,绕晕了)

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 然后我们在运行一下,基本就成了。

7.主页渲染

渲染主页肯定会用到html文件,而这些文件默认会放到和app同级目录下的templates文件夹中,而目前,我们的app在info的__init__文件中。

所以,我们将默认的templates文件夹放到info目录下,同时,将默认的生成的static文件夹也放到里面。

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

操作完成之后,将提供的相关文件放到static文件夹当中,并在templates文件夹中新建一个news文件来存储新闻页所需要的html文件。

操作之后,把我们需要渲染的模板扔到news文件夹下:

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 然后我们修改视图函数中的相关内容,完成页面的渲染就可以了。

from . import index_blue
from flask import render_template


@index_blue.route("/index")
def index():
    """
        主页功能
    :return: 
    """
    return render_template("news/index.html")

8.左侧小log

别的人这个位置都有一个自己的对应的小脚标

看着好看,所有咱们也不能拉下,咱们也得有自己的小脚标

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log

 首先我们导入一个 current_app (是全局的app,通常我们会使用它,避免启动文件换名字带来的修改问题),然后我们给他注册个蓝图

@index_blue.route("/favicon.ico")
def favicon():
    """
    title左侧图标
    :return:
    """

    return current_app.send_static_file("news/favicon.ico")

运行代码,然后他就出来,然后就成了

flask项目——模型类设置以及数据迁移和主页渲染
1. 表间结构分析及模型类准备
2. 建立迁移所用文件夹
3.生成迁移表
 4. 建表
 
5.在MySQL中导入测试数据
6.主页渲染
7.主页渲染
8.左侧小log