flask实战-个人博客-程序骨架、创建数据库模型、临接列表关系

编写程序骨架

personalBlog的功能主要分为三部分:博客前台、用户认证、博客后台,其中包含的功能点如下图所示:


数据库

personalBlog一共需要使用四张表,分别存储管理员(Admin)、分类(Category),文章(Post)和评论(Comment)。

1、创建数据库模型

1)管理员

如果是编写一个固定的个人博客,那么事情就要简单得多,博客的大部分固定信息(比如博客标题,页脚信息等)都可以直接写死在模板中,或是使用自定义的配置存储在配置文件中。但是我们希望编写的是一个通用的博客平台,这就意味着我们要把这些信息的设置交给最终的用户。

为了让博客管理员可以更方便地修改博客信息,我们要提供博客信息(比如博客标题和副标题)修改功能。这些信息不能仅仅定义在配置文件中,而要存储到数据库中。这样用户可以方便地在程序界面修改设置,而不用手动编辑配置文件。

我们将创建一个admin类表示管理员模型,管理员的资料和博客的资料都通过它来保存。

personalBlog/models.py:管理员模型

from personalBlog.extensions import db

class Admin(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    username = db.Column(db.String(20))
    password_hash = db.Column(db.string(128))
    blog_title = db.Column(db.string(60))
    blog_sub_title = db.Column(db.String(100))
    name = db.Column(db.String(30))
    about = db.Column(db.Text)

除了主键字段(id),管理员模型包含存储用户信息和博客资料的字段:用户姓名(name)、密码散列值(password_hash)、博客标题(blog_title)、博客股标题(blog_sub_title)、关于信息(about)。

在这些字段中,我们并没有添加一个password字段来存储密码,取而代之的是一个password_hash字段,后面我们会详细了解具体的原因。

当然,在真实的博客平台中,用户还会拥有更多的可定义设置保存在数据库中,比如用来发送提醒邮件的邮箱服务器、每页显示的文章数量等。这里我们的目标是一个尽量简单的博客平台,所以大部分设置都保存在配置文件中。

2)分类

用于存储文章分类的数据库模型如下所示:

class Category(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(30), unique = True)

分类的名称不允许重复,因此name值将unique参数设为True。

3)文章

存储文章Post模型有标题(title)字段、正文(body)字段以及时间戳(timestamp)字段组成,如下所示:

personalBlog/models.py:文章模型

from datetime import datetime

class Post(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    title = db.Column(db.String(60))
    body = db.Column(db.Text)
    timestamp = db.Column(db.DateTime, default = datetime.utcnow)

在分类和文章之间需要建立一对多关系。我们为Post模型添加了一个category_id外键字段,作为指向分类模型的外键,存储分类记录的主键值,同时在Post类中创建标量关系属性category,在category类中创建集合关系属性posts,如下所示:

class Category(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(30), unique = True)
    posts = db.relationship(‘Post‘, back_populates = ‘category‘)

class Post(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    title = db.Column(db.String(60))
    body = db.Column(db.Text)
    timestamp = db.Column(db.DateTime, default = datetime.utcnow)
    category_id = db.Column(db.Integer, db.ForeignKey(‘category.id‘))
    category = db.relationship(‘Category‘, back_populates = ‘posts‘)

4)评论

用来存储评论的模型类Comment如下所示:

personalBlog/models.py: 评论模型

class Comment(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    author = db.Column(db.String(30))
    email = db.Column(db.String(254))
    site = db.Column(db.String(255))
    body = db.Column(db.Text)
    from_admin = db.Column(db.Boolean, default = False)
    reviewed = db.Column(db.Boolean, default = False)
    timestamp = db.Column(db.DateTime, default = datetime.utcnow, index = True)
    

除了作者(author)、电子邮件(email)、站点(site)、正文(body)这几个常规字段,Comment模型还包含这两个特殊字段:from_admin字段存储布尔值,用来判断评论是否是管理员的评论,默认为False;reviewed字段也存储布尔值,用来判断评论是否通过审核。

添加reviewd字段的主要目的是为了防止垃圾评论和不当评论,当用户发表评论后,评论不会立刻显示在博客中,只有当管理员在博客后台查看并批准后才会显示。

每篇文章都可以包含多个评论,文章和评论之间是一对多双向关系:

class Post(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    title = db.Column(db.String(60))
    body = db.Column(db.Text)
    timestamp = db.Column(db.DateTime, default = datetime.utcnow)
    category_id = db.Column(db.Integer, db.foreignKey(‘category.id‘))
    category = db.relationship(‘Category‘, back_populates = ‘posts‘)
#  cascade:级联操作
    comments = db.relationship(‘Comment‘, back_populates = ‘post‘, cascade = ‘all‘) 

class Comment(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    author = db.Column(db.String(30))
    email = db.Column(db.String(254))
    site = db.Column(db.String(255))
    body = db.Column(db.Text)
    from_admin = db.Column(db.Boolean, default = False)
    reviewed = db.Column(db.Boolean, default = False)
    timestamp = db.Column(db.DateTime, default = datetime.utcnow, index = True)
    post_id = db.Column(db.Integer, db.ForeignKey(‘post.id‘))
    post = db.relationship(‘Post‘, back_populates = ‘comments‘)

Comment模型中创建的外键字段post_id存储Post记录的主键值。我们在这里设置了级联删除,也就是说,当某个记录被删除时,该文章所属的所有评论也会一并被删除,所以在删除文章时不用手动删除对应的评论。

2、临接列表关系

与messageBoard不同,博客程序中的评论要支持存储回复。我们想要为评论添加回复,并在获取某个评论时通过关系属性获得相对应的回复,这样就可以在模板中显示出评论之间的对应关系。那么回复如何存储在数据库中呢?

你当然可以再为回复创建一个Reply模型,然后使用一对多关系将评论和回复关联起来。但是我们将介绍一个更简单的解决办法,因为回复本身也是评论,如果可以在评论模型内建立层级关系,那么就可以在一个模型中表示评论和回复。

这种在同一个模型内的一对多关系在SQLAlchemy中被称为临接列表关系(Adjacency List Relationship)。具体来说,我们需要在Comment模型中添加一个外键指向它自身。这样我们就得到一种层级关系:每个评论对象都可以包含多个评论,即回复。

下面是更新后的comment模型:

class Comment(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    author = db.Column(db.String(30))
    email = db.Column(db.String(254))
    site = db.Column(db.String(255))
    body = db.Column(db.Text)
    from_admin = db.Column(db.Boolean, default = False)
    reviewed = db.Column(db.Boolean, default = False)
    timestamp = db.Column(db.DateTime, default = datetime.utcnow, index = True)
    post_id = db.Column(db.Integer, db.ForeignKey(‘post.id‘))
    post = db.relationship(‘Post‘, back_populates = ‘comments‘)

    replied_id = db.Column(db.Integer, db.ForeignKey(‘comment.id‘))
    replied = db.relationship(‘Comment‘, back_populates = ‘replies‘, remote_side = [id])
    replies = db.relationship(‘Comment‘, back_populates = ‘replied‘, cascade = ‘all‘)
 

在Comment模型中,我们添加了一个replied_id字段,通过db.ForeignKey()设置一个外键指向自身的id字段:

replied_id = db.Column(db.Integer, db.ForeignKey(‘comment.id‘))

关系两侧的关系属性都在Comment模型中定义,需要特别说明的是表示被回复评论(父对象)的标量关系属性replied的定义。

这个关系和我们之前熟悉的一对多关系基本相同。一对多关系中,我们需要在“多”这一侧定义外键,这样SQLAlchemy就会知道哪边是“多”的一侧。这时关系对“多”这一侧来说就是多对一关系。但是在临接列表关系中,关系的两侧都在同一个模型中,这时SQLAlchemy就无法分辨关系的两侧。在这个关系函数中,通过remote_side参数设为id字段,我们就把id字段定义为关系的远程侧(Remote Side),而replied_id就响应地变为本地侧(Local Side),这样反向关系就被定义为多对一,即多个回复对应一个父评论。

集合关系属性replies中的cascade参数设为all,因为我们期望的效果是,当父评论被删除时,所有的自评论也随之删除。

原文地址:https://www.cnblogs.com/xiaxiaoxu/p/10816820.html

时间: 2024-07-30 13:31:58

flask实战-个人博客-程序骨架、创建数据库模型、临接列表关系的相关文章

flask实战-个人博客-模板

模板 personalBlog采用典型的博客布局,左侧三分之二为主体,显示文章列表.正文:右侧三分之一为边栏,显示分为类列表.社交链接等.现在的工作是将HTML文件加工为模板,并创建对应的表单类,在模板中渲染. 并非所有的页面都需要添加边栏,所以我们不能把它放到基模板中.为了避免重复和易于维护,我们把边栏部分的代码放到了局部模板_sidebar.html中.除了基模板base.html和存储宏的macros.html模板,personalBlog程序的博客前台使用的模板如下所示: index.h

flask实战-个人博客-电子邮件支持

电子邮件支持 因为博客要支持评论,所以我们需要在文章有了新评论后发邮件通知管理员.而且,当管理员回复了读者的评论后,也需要发送邮件提醒读者. 为了方便读者使用示例程序,personalBlog中仍然使用Flask-Mail来发送邮件.读者在运行程序前需要在项目根目录内创建.env文件写入对应的环境变量,以便让发信功能正常工作. 因为邮件的内容很简单,我们将直接在发信函数中写出正文内容,这里只提供了HTML正文.我们有两个需要使用电子邮件的场景: 1.当文章有新评论时,发送邮件给管理员: 2.当某

flask实战-个人博客-编写博客前台

编写博客前台 博客前台需要开放给所有用户,这里包括显示文章列表.博客信息.文章内容和评论等功能功能. 分页显示文章列表 为了在主页显示文章列表,我们要先在渲染主页模板的index视图的数据库中获取所有文章记录并传入模板: blueprints\blog.py: from personalBlog.models import Post @blog_bp.route('/') def index(): posts = Post.query.order_by(Post, timestamp.desc(

flask实战-个人博客-使用类组织配置

使用类组织配置 在实际需求中,我们往往需要不同的配置组合.例如,开发用的配置,测试用的配置,生产环境用的配置.为了能方便地在这些配置中切换,你可以把配置文件升级为包,然后为这些使用场景分别创建不同的配置文件,但是最方便的做法是在单个配置文件中使用python类来组织多个不同类别的配置. 下面的代码是personalBlog的配置文件,现在它包含一个基本配置类(BaseConfig),还有其他特定的配置类,即测试配置类(TestingConfig).开发配置类(DevelopmentConfig)

用node.js 搭建的博客程序心得(node.js实战读书笔记1)

学习node已经有一段时间了,之前把了不起的node.js看完了,基本算了解了一些node的基本的用法还有一些概念了,然后就开始看第二本node.js实战,第一章就是搭建一个博客程序.但是不得不吐槽一下node,发展得太块了,很多库已经和之前的用法不一样了,就要一直去百度google来查询最新的用法,其实我觉得这样并不见得是一件好事,因为不稳定,所以就不好学习,就要一直保持对于node的关注.不废话了,这篇文章就大概说一些在这章里面所学习到的一些东西,经验总结吧 1.express - 基于 N

用flask开发个人博客(4)—— flask中4种全局变量

https://blog.csdn.net/hyman_c/article/details/53512109 一  current_app current_app代表当前的flask程序实例,使用时需要flask的程序上下文激活,我们以本专栏第一篇文章中写的test.py为例介绍下它的用法: 1.1 激活程序上下文 [python] view plain copy >>> from test import app >>> from flask import curren

lnmp环境下搭建wordpress博客程序

本文档主要介绍如何在lnmp环境下搭建完整的wordpress程序. 基本流程: 1.开源博客程序WordPress介绍 2.WordPress博客程序的搭建准备 3.开始安装blog博客程序 4.实现WordPress博客程序URL静态化 ---------------------------------------------------------------------------------------------------------------------------------

Debian安装 Nodejs静态博客程序HEXO

1.安装Node.js环境 使用sudo用户,依次执行以下命名: apt-get install curl curl -sL https://deb.nodesource.com/setup | bash - apt-get install -y nodejs - npm应该会自动安装上,可以使用:npm -v 查看npm版本 2.安装HEXO 使用npm包管理器,直接安装hexo npm install hexo -g 进入想保存博客程序的目录执行以下命令,生成相应的基础文件.这里我使用blo

最近写了一个博客程序: QuickBlog PHP 开源的一文多发系统

开始 在开始之前也用到了一些其他类似的系统,区别大概就是非开源的商业化产品不安全,无法进行自我数据存储管理.开源的产品部署起来总有一些问题或者有很多自己想实现的点没有完成. 犹豫了一段时间之后,断断续续写起来当前的这个系统, 主要目的也比较简单,可以在一个地方进行博客/文章撰写,然后可以自动发布到多个平台,通过不同的平台获得提升文章展现量.最后,如果还可以做成独立博客,给搜索引擎蜘蛛抓取,让其他平台进而给自己网站导流,因为你可以很轻易给自己网站增加装饰,甚至增加微薄的广告收入,那就比较完美了.