背景:最近在开发一个flask项目,仿知乎的系统,数据库链接采用sqlalchemy
首页的需求:获取最多赞同和最多评论的文章,排在前面
import math
from flask import Blueprint, render_template, request, abort, flash, redirect, url_for, jsonify
from flask_login import login_required, current_user
from sqlalchemy import func, select, case, desc
from sqlalchemy.orm import aliased
from models import Question, Answer, AnswerComment, db, AnswerLove
@qa.route('/test/')
def test():
# 首页
# 获取赞同的问题id ,with_entities:指定返回的字段
answerlove_qids = [list(q_id) for q_id in AnswerLove.query.with_entities(AnswerLove.q_id).all()]
# 获取回复评论问题id(即有评论的问题)
answer_qids = [list(q_id) for q_id in Answer.query.with_entities(Answer.q_id).filter(Answer.is_valid == 1).all()]
'''左链接查询到问题的id、title、img、desc_、content、get_img_url、love_count(赞同的数量)'''
question_result = (Question.query.outerjoin(AnswerLove, AnswerLove.q_id == Question.id).
with_entities( # 限制返回的字段
Question.id.label('id'), # label:别名
Question.title.label('title'),
Question.img.label('img'),
Question.desc.label('desc_'),
Question.content.label('content'),
case(whens=[(func.length(Question.img) > 0, Question.img)], else_='').label(
"get_img_url"),
func.sum(case(whens=[(Question.id.in_(answerlove_qids), 1)], else_=0)).label("love_count"),
).group_by(Question.id)).subquery() # subquery 子查询
'''左链接查询到评论问题的id、评论数量'''
answer_result = Question.query.outerjoin(Answer, Answer.q_id == Question.id).
with_entities(
Question.id.label('id'),
func.sum(case(whens=[(Question.id.in_(answer_qids), 1)], else_=0)).label("answer_count")
).group_by(Question.id).subquery()
per_page = 3 # 每页条数,可以把它写到配置文件中
try:
page = int(request.args.get('page', 1)) # 获取当前页,如果没有给page,默认就是第1页
if page < 1:
page = 1
except:
page = 1 # 当页码不合法,全部转为第1页
offset = (page - 1) * per_page # 起始页码
# 合并上面2个查询到结果
newstmt = select( # 要查询的字段(c是列的别名)
question_result,
answer_result
).select_from(
question_result.join(answer_result, question_result.c.id == answer_result.c.id)).
order_by(desc(question_result.c.love_count)).order_by(
desc(answer_result.c.answer_count))
article_results = db.session.query(*newstmt.inner_columns).from_statement(newstmt).all() # 没有分页前的数据
pages = math.ceil(len(article_results) / per_page) # 计算页数:向上取整
pageresult = db.session.query(*newstmt.inner_columns).from_statement(newstmt.offset(offset).limit(per_page))
return render_template('indexnew.html', page_data=pageresult, pages=pages, per_page=per_page, currentpage=page)
分页组件:
{# 分页组件 #}
{# //分页组件 #}



