【Flask】个人博客、资讯项目关键点总结

本文总结了使用Flask框架构建个人博客和资讯项目的要点,包括图片验证码生成与验证、短信验证码发送、用户注册与登录、个人中心的图片上传、新闻发布与分类、新闻展示逻辑、点击量统计、收藏功能以及后台权限控制等关键功能的实现。涉及到的技术包括Redis存储、云通讯服务、第三方图片上传和数据库操作。
摘要由CSDN通过智能技术生成
  • 图片验证码

uuid:前端js生成,时间戳+机器码+随机数,(image_code_id)

图片验证码:captcha生成,→name,text,image

在redis中保存图片验证码文本,(uuid,过期时间,text)

向前端返回图片验证码的图片,response = make_response(image)

  • 发送短信

从redis获取真实验证码,读完之后删除,

先比较图片验证码:real_image_code.lower() != image_code.lower():

通过手机号查询数据库,看是否已注册

生成短信验证码:sms_code = '%06d' % random.randint(0, 999999)

保存短信验证码:手机号,过期时间,验证码

调用云通讯发送

  • 注册

检查用户是否已注册

user = User.query.filter(User.mobile == mobile).first()

提交用户数据到数据库

db.session.add(user)

db.session.commit()

db.session.rollback()

缓存用户数据到redis中:

请求上下文中有request和session两个对象,一个负责处理http请求内容,一个负责处理用户信息。

判断用户名和密码正确(一起判断,避免反向解析)

   

 if user is None or not user.check_password(password):

g 保存的是当前请求的全局变量,不同的请求会有不同的全局变量,通过不同的thread id区别

  • 个人中心

获取图片

avatar = request.files.get('avatar')

读取成二进制

image_data = avatar.read()

利用第三方上传图片

给我们返回一个图片名

我们需要拼接上云空间的链接+图片名,返回给前端

  • 发布新闻

查询所有分类,放到一个列表中,移除最新分类,category_list.pop(0)

通过request获取表单和文件数据

检查参数完整性

然后需要将获取的图片读取成二进制形式

调用第三方工具上传图片

闻图片对新闻来说是一个整体,也要一起存储到mysql中,

  • 用户登录后首页的展示

这里主要是数据库的查询,然后组装给模板的数据,(字典格式)

return render_template('news/index.html',data=data)

  • 加载logo图标
# 加载logo图标,浏览器默认请求跟路径下

@news_blue.route('/favicon.ico')

def favicon():

    # 发送文件给浏览器

    return current_app.send_static_file('static/favicon.ico')
  • 点击分类时的展示逻辑
    # 判断新闻分类,*filters是拆包,如果前端点击的是1(cid=1)分类,列表为空,查所有;如果大于1,则查询cid对应的分类(通过模型类)

filters = []

if cid >1:

        filters.append(News.category_id == cid)

    try:

        paginate = News.query.filter(*filters).order_by(News.create_time.desc()).paginate(page,per_page,False)

组装字典,向前端返回数据

  • 点击排行的展示

查询数据库通过点击量排序,获取指定条数据

news_list = News.query.order_by(News.clicks.desc()).limit(6)

整理成前端需要的格式

news_click_list = []

    for news in news_list:

        news_click_list.append(news.to_dict())

  • 小点,点击过新闻后,点击次数加1

新闻详情:news = News.query.get(news_id)

新闻点击次数加1:news.clicks += 1

记得要提交到数据库

  • 收藏功能

首先要判断用户是否登录:user = g.user

需要检查参数:新闻id和收藏状态action

注意:一条新闻不能被收藏两次

  • 后台界面
# 点击了收藏

if action == 'collect':

        # 判断用户是否收藏过(一条新闻不能被收藏两次)

        if news not in user.collection_news:

            user.collection_news.append(news)

    else:

        user.collection_news.remove(news)
  • 权限控制

避免普通用户登录到后台界面,使用请求钩子在每次访问前进行判断,判断是否请求登录页面,是否有用户登录,是否是管理员,条件不满足直接重定向到主页

@admin_blu.before_request
def before_request():
    # 判断如果不是登录页面的请求
    if not request.url.endswith(url_for("admin.admin_login")):
        user_id = session.get("user_id")
        is_admin = session.get("is_admin", False)

        if not user_id or not is_admin:
            # 判断当前是否有用户登录,或者是否是管理员,如果不是,直接重定向到项目主页
            return redirect('/')
  • 退出后要清除session中管理员数据
   session.pop('user_id', None)
   session.pop('nick_name', None)
   session.pop('mobile', None)
   session.pop('is_admin', None)
  • 注意

界面提示 The CSRF token is missing

<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
  • 查询总人数

除去管理员

total_count = User.query.filter(User.is_admin == False).count()
  • 查询月新增人数
mon_count = 0
    try:
        now = time.localtime()
        mon_begin = '%d-%02d-01' % (now.tm_year, now.tm_mon)
        mon_begin_date = datetime.strptime(mon_begin, '%Y-%m-%d')
        mon_count = User.query.filter(User.is_admin == False, User.create_time >= mon_begin_date).count()
    except Exception as e:
        current_app.logger.error(e)
 
  • 查询日新增人数
day_count = 0 
try: 
    day_begin = '%d-%02d-%02d' % (now.tm_year, now.tm_mon, now.tm_mday) 
    day_begin_date = datetime.strptime(day_begin, '%Y-%m-%d') 
    day_count = User.query.filter(User.is_admin == False, User.create_time >             day_begin_date).count() 
except Exception as e: 
    ​​​​​​​current_app.logger.error(e)
  • 获取每天活跃人数
# 获取到当天00:00:00时间

    now_date = datetime.strptime(datetime.now().strftime('%Y-%m-%d'), '%Y-%m-%d')
    # 定义空数组,保存数据
    active_date = []
    active_count = []

    # 依次添加数据,再反转
    for i in range(0, 31):
        begin_date = now_date - timedelta(days=i)
        end_date = now_date - timedelta(days=(i - 1))
        active_date.append(begin_date.strftime('%Y-%m-%d'))
        count = 0
        try:
            count = User.query.filter(User.is_admin == False, User.last_login >= day_begin,
                                      User.last_login < day_end).count()
        except Exception as e:
            current_app.logger.error(e)
        active_count.append(count)

    active_date.reverse()
    active_count.reverse()

    data = {"total_count": total_count, "mon_count": mon_count, "day_count": day_count, "active_date": active_date,
            "active_count": active_count}
  • 按用户登录时间倒序展示用户列表
paginate = User.query.filter(User.is_admin == False).order_by(User.last_login.desc()).paginate(page, constants.ADMIN_USER_PAGE_MAX_COUNT, False)
users = paginate.items
current_page = paginate.page
total_page = paginate.pages
将模型列表转成字典

users_list = [] 
for user in users: 
    users_list.append(user.to_admin_dict()) 
    context = {"total_page": total_page, "current_page": current_page, "users": users_list} 

return render_template('admin/user_list.html',data=context)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值