DAY18 个人中心 修改密码 新闻收藏

后端代码

新建视图

user模块的views文件下,视图建好之后就可以去user的HTML中对应的模块中把路由进行更改。

 

 对请求方式进行设置,接收两种请求,页面渲染和用户填写的密码。

对应的文档注释,视图功能和思路步骤

 

 这里参数接收了全部,前端校验,后端也一起做了。

# 1. 校验用户登录状态
    user = g.user
    if not user:
        return redirect(url_for("index.index"))

 个人中心是所有操作只有当用户登录后才能进行,先判断登录

GET请求:

# 2. 根据不同的请求来进行不同的操作
#   2.1 GET 请求
    if request.method == "GET" :
#        2.1.2 页面渲染
        return render_template("news/user_pass_info.html") 

 

渲染页面的HTML文件不要忘记放在templates文件夹下,这里不需要传参给前端

POST请求:

    # 2.2 POST 请求
    if request.method == "POST":
#       2.2.1  接收参数(old_password,new_password,new_password2)
        old_password  = request.json.get("old_password")
        new_password  = request.json.get("new_password")
        new_password2  = request.json.get("new_password2") 

从前端的ajax中接收对应的参数,json格式。用户当前密码,输入的密码,确认第一次输入的密码

#       2.2.2  校验参数
        #a参数是否齐全
        if not all([old_password,new_password,new_password2]):
            return jsonify(errno=RET.PARAMERR,errmsg="缺失参数")
        #b密码是否正确
        if not user.check_password(old_password):
            return jsonify(errno=RET.PARAMERR, errmsg="原密码错误")
        #c输入的两次密码是否一致
        if  new_password != new_password2:
            return jsonify(errno=RET.PARAMERR,errmsg="两次密码输入不一致") 

 

这里先整体校验参数是否齐全,然后对旧密码是否正确也进行了校验,因为我们存入数据库的密码是进行过加密的

所以我们通过在模型类里加入校验函数并调用了函数来进行 判断,同登录时 的操作。详情去登录看

这里还可以加一个修改后的密码不能同旧密码,也就是加一个判断操作就可以了,但是要在校验完两次密码一致后进行

两个参数随便找一个进行比较就行,第一次输入的和第二次输入的都行。因为我们是在它们判断一致后再进行的

#       2.2.3 根据传入的值修改user的相关信息
        user.password = new_password2
        try:
            db.session.commit()
        except Exception as e :
                current_app.logger.error(e)
                db.session.rollback()
                return jsonify(errno=RET.DBERR,errmsg="数据库连接异常")
#       2.2.4 返回json数据
        return jsonify(errno=RET.OK,errmsg="修改成功")

 

完成之后对我们找到的user对象进行修改,这里的password是一个函数,也就是我们的加密密码的函数,用了类方法来进行使用

也就是装饰器,完成后返回json数据来让回调函数执行。

 

完整代码

@user_blue.route("/pass_info",methods = ["GET","POST"])
@user_login_data
def pass_info():
    """
    用户密码修改
    1. 校验用户登录状态
    2. 根据不同的请求来进行不同的操作
     2.1 GET 请求
       2.1.2 页面渲染
     # 2.2 POST 请求
     #   2.2.1  接收参数(old_password,new_password,new_password2)
     #   2.2.2  校验参数
     #   2.2.3 根据传入的值修改user的相关信息 
     #   2.2.4 返回json数据 
    :return: 
    """
# 1. 校验用户登录状态
    user = g.user
    if not user:
        return redirect(url_for("index.index"))
# 2. 根据不同的请求来进行不同的操作
#   2.1 GET 请求
    if request.method == "GET" :
#        2.1.2 页面渲染
        return render_template("news/user_pass_info.html")

    # 2.2 POST 请求
    if request.method == "POST":
#       2.2.1  接收参数(old_password,new_password,new_password2)
        old_password  = request.json.get("old_password")
        new_password  = request.json.get("new_password")
        new_password2  = request.json.get("new_password2")
#       2.2.2  校验参数
        #a参数是否齐全
        if not all([old_password,new_password,new_password2]):
            return jsonify(errno=RET.PARAMERR,errmsg="缺失参数")
        #b密码是否正确
        if not user.check_password(old_password):
            return jsonify(errno=RET.PARAMERR, errmsg="原密码错误")
        #c输入的两次密码是否一致
        if  new_password != new_password2:
            return jsonify(errno=RET.PARAMERR,errmsg="两次密码输入不一致")
#       2.2.3 根据传入的值修改user的相关信息
        user.password = new_password2
        try:
            db.session.commit()
        except Exception as e :
                current_app.logger.error(e)
                db.session.rollback()
                return jsonify(errno=RET.DBERR,errmsg="数据库连接异常")
#       2.2.4 返回json数据
        return jsonify(errno=RET.OK,errmsg="修改成功") 

 

前端代码

HTML

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>用户中心</title>
	<link rel="stylesheet" type="text/css" href="../../static/news/css/reset.css">
	<link rel="stylesheet" type="text/css" href="../../static/news/css/main.css">
        <script type="text/javascript" src="../../static/news/js/jquery-1.12.4.min.js"></script>
    <script type="text/javascript" src="../../static/news/js/user_pass_info.js"></script>
</head>
<body class="inframe_body">
    <form class="pass_info">
        <h3>密码修改</h3>
        <div class="form-group">
            <label>当前密码:</label>
            <input type="password" name="old_password" class="input_txt">
        </div>
        <div class="form-group">
            <label>新密码:</label>
            <input type="password" name="new_password" class="input_txt">
        </div>
        <div class="form-group">
            <label>确认密码:</label>
            <input type="password" name="new_password2" class="input_txt">
        </div>
       <div class="error_tip">提示信息</div>
        <div class="form-group">
            <input type="submit" value="保 存" class="input_sub">
        </div>
    </form>
</body>
</html>

  

JS代码

function getCookie(name) {
    var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
    return r ? r[1] : undefined;
}


$(function () {
    $(".pass_info").submit(function (e) {
        e.preventDefault();

        // TODO 修改密码
        var params = {};
        $(this).serializeArray().map(function (x) {
            params[x.name] = x.value;
        });
        // 取到两次密码进行判断
        var new_password = params["new_password"];
        var new_password2 = params["new_password2"];

        if (new_password != new_password2) {
            alert('两次密码输入不一致')
            return
        }

        $.ajax({
            url: "/user/pass_info",
            type: "post",
            contentType: "application/json",
            headers: {
                "X-CSRFToken": getCookie("csrf_token")
            },
            data: JSON.stringify(params),
            success: function (resp) {
                if (resp.errno == "0") {
                    // 修改成功
                    alert("修改成功");
                    window.location.reload();
                }else {
                    alert(resp.errmsg)
                }
            }
        });
    });
});

  

 

新闻收藏

后端代码

还是在user模块的views文件中新建视图

 这里GET请求就可以了,当前页数通过?+键值对 构建在URL中,然后接收就可以了

    user = g.user
    if not user:
        return redirect(url_for("index.index"))

获取用户数据除了判断之外我们后面也可以通过用户来进行查询,查询用户收藏的所有新闻

#   2. 接收参数
    page = request.args.get("p",1)

这里设置了默认值来确保数据一定有,就不用对数据是否存在进行校验了,更好的用户体验

#   3.校验参数
    try:
        page = int(page)
    except Exception as e :
            current_app.logger.error(e)
            page = "1"

 这里对数据是否为整型进行了校验并作出了处理,这里的处理也是为了更好的用户体验

#   4.分页查询:user.collection_news == BaseQuery类型的对象
    paginate = None
    try:
        paginate = user.collection_news.paginate(page,constants.USER_COLLECTION_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据读取失败")
  

user.collection_news是一个查询字段关联着我们的新闻收藏表,也就是通过第三表来获取新闻对象,这里也是进行分页处理,方便用户参看

user.collection_news == BaseQuery类型的对象,可以直接进行分页处理返回的是一个分页器,位置参数为当前页,以及每页展示的新闻数为多少

,这里通过文件.的形式来进行设置,方便后面变更

paginate只是一个分页器,通过.的形式来进行数据获取,数据库查询第三方操作,放在try里面,并且对paginate进行了默认值设置。

#   5.构造渲染模板的数据
    news_list = paginate.items
    total_page = paginate.pages
    current_page = paginate.page
    news_dict_list = []
    for news in news_list :
        news_dict_list.append(news.to_basic_dict())

.items获取新闻对象

.pages 获取总页数,也就是数据分了多少页

.page 获取当前页。通过前端传入的数据来劲、进行不同页数据的展示,实现分页展示

并且对新闻数据进行了字典化构造新的列表数据传给前端进行渲染

#   4. 构造上下文
    context = {
        "news_list": news_dict_list,
        "total_page" : total_page,
        "current_page" : current_page
    }
#   5.页面渲染
    return render_template("news/user_collection.html",**context)

  

返回页面和构造的数据上下文,数据有:所有的新闻字典列表,总页数,当前页。方便前端进行数据的展示。 

 整体代码

 

@user_blue.route("/user_collection",methods = ["GET"])
@user_login_data
def user_collection():
    """
    用户收藏
    1.校验用户登录状态
    2.接收参数
    3.校验参数
    4. 获取用户收藏,并分页
    5.获取收藏时间
    6.构造上下文
    7. 页面渲染
    :return: 
    """
#   1.校验用户登录状态
    user = g.user
    if not user:
        return redirect(url_for("index.index"))
#   2. 接收参数
    page = request.args.get("p",1)
#   3.校验参数
    try:
        page = int(page)
    except Exception as e :
            current_app.logger.error(e)
            page = "1"
#   4.分页查询:user.collection_news == BaseQuery类型的对象
    paginate = None
    try:
        paginate = user.collection_news.paginate(page,constants.USER_COLLECTION_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据读取失败")
#   5.构造渲染模板的数据
    news_list = paginate.items
    total_page = paginate.pages
    current_page = paginate.page
    news_dict_list = []
    for news in news_list :
        news_dict_list.append(news.to_basic_dict())
#   4. 构造上下文
    context = {
        "news_list": news_dict_list,
        "total_page" : total_page,
        "current_page" : current_page
    }
#   5.页面渲染
    return render_template("news/user_collection.html",**context)

 

  

 

前端HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户中心</title>
    <link rel="stylesheet" type="text/css" href="../../static/news/css/reset.css">
    <link rel="stylesheet" type="text/css" href="../../static/news/css/jquery.pagination.css">
    <link rel="stylesheet" type="text/css" href="../../static/news/css/main.css">
    <script type="text/javascript" src="../../static/news/js/jquery-1.12.4.min.js"></script>
    <script type="text/javascript" src="../../static/news/js/jquery.pagination.min.js"></script>
</head>
<body class="inframe_body">
    <div class="my_collect">
        <h3>我的收藏</h3>
        <ul class="article_list">
            {% for news in news_list %}
                <li><a href="#">{{ news.title }}</a><span>{{ news.create_time }}</span></li>
            {% endfor %}
        </ul>



        <div id="pagination" class="page"></div>
        <script>
{#            这是使用的是分页框架#}
            $(function() {
                $("#pagination").pagination({
                    currentPage: {{ current_page }},
                    totalPage: {{total_page }},
{#                    当用户的鼠标点击哪一页的时候自动执行下面的事件#}
                    callback: function(current) {
                        window.location.href = '/user/user_collection?p=' + current;
                    }
                });
            });
        </script>

    </div>
</body>
</html>

  

通过循环来进行收藏新闻的展示,并且进行分页展示处理,注意只有当用户收藏的新闻超过一页,也就是大于了设置的每页新闻展示个数才会出现

分页框

 

 当超过时:(如果你想数据少点就展示就修改展示页数就可以了)

 

 

 

 

在url_for中加入键值对

 

posted @ 2021-11-01 22:14  和风的夏天  阅读(118)  评论(0)    收藏  举报