DAY19 后台管理

项目的后台管理需要超级管理员才能进入,我们需要同过脚本命令来创建

代码:

@manager.option("-n","-昵称",dest ="nick_name")
@manager.option("-m","-手机号",dest ="mobile")
@manager.option("-p","-密码",dest ="pwd")
def createsuperuser(nick_name,mobile,pwd):
    """
    生成超级管理员账号
    :param nick_name: 昵称
    :param mobile: 手机
    :param pwd: 密码
    :return: 
    """
    if not all([nick_name,mobile,pwd]) :
        print("缺失参数,创建失败")
        return
    superuser = User()
    superuser.nick_name = nick_name
    superuser.mobile = mobile
    superuser.password = pwd
    superuser.is_admin = True
    try:
        db.session.add(superuser)
        db.session.commit()
    except Exception as e :
            current_app.logger.error(e)
            db.session.rockback()
            print("创建失败")
            return
    print("创建成功!")@manager.option("-n","-昵称",dest ="nick_name")
@manager.option("-m","-手机号",dest ="mobile")
@manager.option("-p","-密码",dest ="pwd")
def createsuperuser(nick_name,mobile,pwd):
    """
    生成超级管理员账号
    :param nick_name: 昵称
    :param mobile: 手机
    :param pwd: 密码
    :return: 
    """
    if not all([nick_name,mobile,pwd]) :
        print("缺失参数,创建失败")
        return
    superuser = User()
    superuser.nick_name = nick_name
    superuser.mobile = mobile
    superuser.password = pwd
    superuser.is_admin = True
    try:
        db.session.add(superuser)
        db.session.commit()
    except Exception as e :
            current_app.logger.error(e)
            db.session.rockback()
            print("创建失败")
            return
    print("创建成功!")

 

需要借助manger脚本对象来完成,然后在控制台输入命令里执行,跟数据迁移差不多

后台管理还有主页和登录页面,超级管理员也是在用户表里面,但是多了权限,也就是is_admin为TURE,session里也多加入了字段来进行判断

是否为超级用户

这一块需要新的模块注册新的蓝图

admin模块

主页面视图代码(需要判断是否为超级管理员才能进入)

@admin_blue.route("/index")
@user_login_data
def admin_index():
    user = g.user
    if not user:
        return redirect(url_for("admin.admin_login"))
    if not session.get("is_admin"):
        return redirect(url_for("admin.admin_login"))
    context ={
        "user":user
    }
    return render_template("admin/index.html",**context)

 

登录视图

@admin_blue.route("/login",methods = ["POST","GET"])
def admin_login():
    """
    管理员登录
    GET请求:渲染页面
    POST请求:
    1.接收参数
    2.校验参数
    3.判断权限
    4.状态保存
    5.返回结果
    :return: 
    """
# GET请求:渲染页面
    if request.method == "GET":
        return render_template("admin/login.html")
#     POST请求:
    if request.method == "POST":
#     1.接收参数
        username = request.form.get("username")
        password = request.form.get("password")
#     2.校验参数
        if not all([username, password]):
            return render_template("admin/login.html", errmsg="密码或手机号缺失")
        try:
            user = User.query.filter_by(mobile=username).first()
        except Exception as e :
                current_app.logger.error(e)
                return render_template("admin/login.html", errmsg="密码或手机号错误")
        if not user :
            return render_template("admin/login.html", errmsg="密码或手机号错误")
        if not user.check_password(password):
            return render_template("admin/login.html", errmsg="密码或手机号错误")
#     3.判断权限
        if not user.is_admin :
            return render_template("admin/login.html", errmsg="对不起,权限不够")
#     4.状态保存
        session["nick_name"]=user.nick_name
        session["mobile"]=user.mobile
        session["user_id"]=user.id
        session["is_admin"]= 1
#     4.返回结果
        return redirect(url_for("admin.admin_index"))

  

用户统计

 

 

 这个页面渲染后端传需要五个数据,我们来逐个实现

第一用户总数,代码

 total_count = 0
    try:
        total_count = User.query.filter_by(is_admin = False).count()
    except Exception as e :
            current_app.logger.error(e)

 查询USER数据库中所有的数据,但是有条件,超级管理员不要。也就是is_admin =False,count()执行器可以直接获取查询到的对象数量,需要记一下使用

第二,月新增数,

这个需要从所有的用户数据中判断创建时间大于本月1号的所有用。需要使用到time,datatime模块一起实现

 补充(time,datatime)

import time,datetime
a=time.localtime()#当前时间对象
print(a)
b = "%s-%02d-%02d" % (a.tm_year,a.tm_mon,a.tm_mday)#构造符合时间数据类型的字符串
c = datetime.datetime.strptime(b ,"%Y-%m-%d") #将字符串转换为时间数据类型
print(c)
d =datetime.timedelta(days=1) #获取一天的时间量,用于和时间变量进行时间加减,单体没有意义
print(d)

 time.localtime()生成当前时间对象,我们可以通过获取对象属性来构建对应的时间数据数据,然后再进行比较

 

 代码:

month_count = 0
    now = time.localtime()
    month_str = "%s-%2d-01" % (now.tm_year,now.tm_mon) #构造当前月份的一号时间默认为00:00:00,也就是1号开始
    month_str_date = datetime.datetime.strptime(month_str,"%Y-%m-%d")
    try:
        month_count = User.query.filter(User.is_admin == False, User.create_time > month_str_date).count()
    except Exception as e :
            current_app.logger.error(e)

  查询条件有比较的条件产生时要使用filter来进行,不能使用filter_by,这点要注意,这里只要用户的创建时间大于1号 的开始就说明是这个月新建的用户。count获取数量

 

第三,用户新增数

代码:

 day_count = 0
    day_str = "%s-%2d-%2d" % (now.tm_year,now.tm_mon,now.tm_mday)
    day_str_date = datetime.datetime.strptime(day_str,"%Y-%m-%d")
    try:
        day_count = User.query.filter(User.is_admin == False, User.create_time >day_str_date ).count()
    except Exception as e :
            current_app.logger.error(e)

 同每月新增一样,我们只需要比较创建时间大于当前的开始时间就可以了,也就是00:00:00,通过time,datatime来完成,这里不需要再小于当前的结束,就目前来说,结束属于未来时间,我们time获取不到明天的时间

第四,x轴数据和Y轴数据

折现图的显示是前端来完成的,我们只需要将数据传递给前端模板来完成就可以了,也就是x轴和y轴的数据

我们决定传什么数据就可以了,这里x轴传每一天的活跃量,也就是用户的最后一次登录时间属于当天的范围内

Y轴传15天的数据,也就是从当前时间开始前15天的内容,这里传开始,如果传当前的结束的话也是未来时间,不太好

我们通过循环15次来获取15天的数据并传给前台

代码:

 x_data = []
    y_data = []
    today_count = 0
    for i in range(0,15): #循环
        day_begin = day_str_date - datetime.timedelta(days=i) #i代表需要减几天的时间量
        day_end = day_begin + datetime.timedelta(days=1)     #当前时间开始加1天的时间量为结束
        today_begin = datetime.datetime.strftime(day_begin,"%Y-%m-%d")
        x_data.append(today_begin)  #渲染日期开始

        try:
            today_count = User.query.filter(User.is_admin == False, User.last_login > day_begin,
                                          User.last_login < day_end).count()    #三个条件获取日活跃量,last_login为最后一次登录时间
        except Exception as e :
                current_app.logger.error(e)
        y_data.append(today_count)
    x_data.reverse()  #因为是从最开始减到最后,所以需要翻转,不然会从当前时间到之前的时间
    y_data.reverse() #和日期是对应的关系

  

前端需要列表数据所以我们将数据构造成列表,而且每天用户的活跃度为当天开始到第二天开始的范围内,也就是说虽然我们Y轴展示的是当前的开始日期,但是还是将当天登录的用户给查询了,并给到了前台。并不会出现当前天

没有活跃的情况

前端渲染要使用过滤器safe。

完整代码

@admin_blue.route("/user_count")
def user_count():
    """
    用户统计
    :return: 
    """
    total_count = 0
    try:
        total_count = User.query.filter_by(is_admin = False).count()
    except Exception as e :
            current_app.logger.error(e)

    month_count = 0
    now = time.localtime()
    month_str = "%s-%2d-01" % (now.tm_year,now.tm_mon)
    month_str_date = datetime.datetime.strptime(month_str,"%Y-%m-%d")
    try:
        month_count = User.query.filter(User.is_admin == False, User.create_time > month_str_date).count()
    except Exception as e :
            current_app.logger.error(e)

    day_count = 0
    day_str = "%s-%2d-%2d" % (now.tm_year,now.tm_mon,now.tm_mday)
    day_str_date = datetime.datetime.strptime(day_str,"%Y-%m-%d")
    try:
        day_count = User.query.filter(User.is_admin == False, User.create_time >day_str_date ).count()
    except Exception as e :
            current_app.logger.error(e)
    x_data = []
    y_data = []
    today_count = 0
    for i in range(0,15):
        day_begin = day_str_date - datetime.timedelta(days=i)
        day_end = day_begin + datetime.timedelta(days=1)
        today_begin = datetime.datetime.strftime(day_begin,"%Y-%m-%d")
        x_data.append(today_begin)

        try:
            today_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)
        y_data.append(today_count)
    x_data.reverse()
    y_data.reverse()


    context ={
        "total_count": total_count,
        "month_count" : month_count,
        "day_count" : day_count,
        "x_data" :x_data,
        "y_data" : y_data
    }
    return render_template("admin/user_count.html",**context)

  

 

 

 

 

 

  

posted @ 2021-11-04 22:30  和风的夏天  阅读(72)  评论(0)    收藏  举报