首页 > 其他分享 >使用axum构建博客系统 - 文章详情

使用axum构建博客系统 - 文章详情

时间:2023-10-21 20:33:27浏览次数:37  
标签:category axum dateline pub name topic 博客 id 详情

本章将实现博客文章的详情显示功能。

数据库视图

CREATE VIEW v_topic_cat_detail AS
  SELECT t.id, title, html, hit, dateline,category_id,t.is_del,
         c.name AS category_name
    FROM
      topics AS t
      INNER JOIN categories AS c
          ON t.category_id=c.id
   WHERE c.is_del = false
         ;

该视图和v_topic_cat_list唯一不同的地方在于,它要的是topicshtml字段。

数据模型

// src/model.rs
#[derive(PostgresMapper, Serialize)]
#[pg_mapper(table="v_topic_cat_detail")]
pub struct TopicDetail{
    pub id:i64,
    pub title: String,
    pub category_id:i32,
    pub html:String,
    pub hit:i32,
    pub dateline:time::SystemTime,
    pub is_del:bool,
    pub category_name:String,
}
impl TopicDetail {
    pub fn dateline(&self) ->String {
        dateline(self.dateline.clone())
    }
}

fn dateline(dt:time::SystemTime) -> String {
    let ts = dt.duration_since(time::UNIX_EPOCH).unwrap_or(time::Duration::from_secs(0)).as_secs() as i64;
    Local.timestamp(ts, 0).format("%Y/%m/%d %H:%M:%S").to_string()
}

这里新增了 dateline()函数,用于将时间以字符串的形式显示。为了代码重用,TopicList::dateline()也重构为调用该函数

// src/model.rs
impl TopicList {
    pub fn dateline(&self) ->String {
        dateline(self.dateline.clone())
    }
}

模板

文章详情的模板位于templates/frontend/topic_detail.html,请自行查看。

视图类

文章详情的视图类位于src/view/frontend/topic.rs,请自行查看。

handler

// src/handler/frontend/topic.rs

pub async fn detail(
    Extension(state): Extension<Arc<AppState>>,
    Path(id): Path<i64>,
) -> Result<HtmlView> {
    let handler_name = "frontend/topic/list";
    let client = get_client(&state).await.map_err(log_error(handler_name))?;
    let cats = category::list(&client)
        .await
        .map_err(log_error(handler_name))?;
    let archives = topic::archive_list(&client)
        .await
        .map_err(log_error(handler_name))?;
    let state = state.clone();
    let item = topic::detail(&client, id).await.map_err(log_error(handler_name))?;
    let tmpl = Detail {
        cats,
        archives,
        item,
    };
    render(tmpl).map_err(log_error(handler_name))
}

topic::detail()用于通过id获取文章详情。

数据库操作

pub async fn detail(client: &Client, id: i64) -> Result<TopicDetail> {
    super::execute(client, "UPDATE topics SET hit=hit+1 WHERE id=$1", &[&id]).await ?;
    let sql = "SELECT id,title,category_id,html,hit,dateline,is_del,category_name FROM v_topic_cat_detail WHERE is_del=false and id=$1 LIMIT 1";
    super::query_row(client, sql, &[&id]).await
}

首先,使文章的浏览次数加1,然后返回文章的数据。

前面章节说过,Postgresql支持RETURNING,为什么此处要写两句SQL?

原因在于,我们需要返回的数据来自于视图,如果:

  • 直接UPDATE topics...RETURNING ...并不能满足所需要的字段,比如category_name
  • 视图原则上是只读的,所以不能UPDATE v_topic_cat_detail...RETURING... 

另外,此处不需要用事务,因为如果UPDATE出错,那么整个函数都退出了(返回值是Err(AppError))——除非你把SELECT写在UPDATE前面。

路由

本功能的路由定义在src/handler/frontend/mod.rs文件。

标签:category,axum,dateline,pub,name,topic,博客,id,详情
From: https://www.cnblogs.com/pythonClub/p/17779467.html

相关文章

  • 使用axum构建博客系统 - 存档文章列表
    本章将实现存档文章列表功能。注意,本章涉及较多PostgreSQL知识,如果你对相关知识不熟悉,可以先让代码跑起来,再去了解相关知识。模板本功能模板文件是templates/frontend/topic_arch.html。视图类本功能视图类定义在src/view/frontend/topic.rs文件。handler//src/handler/fro......
  • 每日博客
    1.Hive是由Facebook公司开发的一个构建在Hadoop之上的数据仓库工具,在某种程度上可以看作是用户编程接口,其本身并不存储和处理数据2.Hive一般依赖于分布式文件系统HDFS,而传统数据库则依赖于本地文件系统,Hive和传统关系数据库都支持分区,传统关系数据库很难实现横向扩展,Hive具......
  • 博客园主题美化
    一、首页主题预览二、主题部署1.开通js权限2.css代码禁用css模板点击查看代码#loading{bottom:0;left:0;position:fixed;right:0;top:0;z-index:9999;background-color:#f4f5f5;pointer-events:none;}.loader-inner{will-change:transform;width:40px;height:40px;positi......
  • 模拟集成电路设计系列博客——3.1.3 稳压电路
    3.1.3稳压电路稳压器的目标是产生一个低噪声并能提供电流的电压源。他们一般来说用于这种情节:当一个关键模拟电路必须和其他的电路工作在同一个电源供电下时。如下图所示,其他的电路向共用的电源中引入了很大的噪声,使用稳压器可以为关键电路提供一个更加干净的电源。数字电路一般......
  • 模拟集成电路设计系列博客——3.1.2 参考电路
    3.1.2参考电路已知绝对值的电压和电流在集成电路的交互处,或者是集成电路和其他分立部件之间是最有用的。例如,两个集成电路需要交互时,规定通过一伏摆幅的信号来进行。参考电压或者电流优势从电源中分配而出,但电源并不重组有着充足的控制精度,这种情况下参考电压或者参考电流就需要......
  • 从零用VitePress搭建博客教程(4) – 如何自定义首页布局和主题样式修改?
    接上一节:从零用VitePress搭建博客教程(3)-VitePress页脚、标题logo、最后更新时间等相关细节配置六、首页样式修改有时候觉得自带的样式不好看,想自定义,首先我们在docs/.vitePress新建一个theme文件夹,用来存放自定义布局和主题修改的相关文件,如下所示theme下再新建custom.css......
  • 【玩转 EdgeOne】边缘安全加速平台EO给自己的技术博客插上“翅膀”
    作为一个技术博客爱好者,不知不觉已经在程序员行业将近十年了,写技术博客也有将近七年的时间,其中我也搭建了一个自己的技术博客,因为服务器购买的是比较低配的云服务器,技术博客的访问速度不是很理想。近期发现腾讯云推出的边缘安全加速平台可以起到访问加速和安全防护的作用,我这边非常......
  • 爬取博客园新闻
    目录代码结果展示代码importrequestsfrombs4importBeautifulSoupfrommultiprocessingimportPoolimportsqlite3importtimefromtqdmimporttqdmyour_cookie="your_cookie"headers={'Accept':'text/html,application/xhtml+xml,ap......
  • 第一次博客——分享C语言学习
    今天又是在寝室里学习C语言的一天,学校里老师上课有点水,只能自己学习,幸好有比特鹏哥的帮助,C语言水平稳步增长。今天在鹏哥的带领下,学习了选择语句和循环语句。选择语句学习了if结构和switch结构,个人感觉switch结构虽然适用于多分支比较方便,但整型的限制比较大,很多语句后都不能遗忘br......
  • 博客成立啦!亲爱的小博,以后将会和你共同记录下我的成长路上的点点滴滴!加油!
    大学中的第一篇博客来啦~初秋的落叶承载了新一轮的悲欢离合,校园的晚霞昭示着再一次的轻装上阵,或许像那句话所说“我们出发,皆因我们相信,也因我们可以”。我们相信前路坎坷但意义非凡,勇敢向前不惧阻挠。我们可以迎接挑战并全力以赴,不负韶华再赴前章。夏末不能仅仅停留在遗憾的书......