flask爱家租房项目开发(七)

本文对应的资料下载地址:https://download.csdn.net/download/geek_xiong/11548649

目录

个人主页显示用户信息

后端代码编写

前端代码编写

个人信息修改界面的完善

个人信息的显示

前端代码编写

用户名的修改操作

后端代码编写

前端代码编写

实名信息认证

实名信息的显示

后端代码编写

前端代码编写

实名信息认证

后端代码编写

前端代码编写

城区信息

后端代码编写

缓存数据库

前端代码编写


个人主页显示用户信息

在主页点击用户名,进入个人主页my.html

界面应该显示用户的头像,用户名以及手机号

url:127.0.0.1:5000/api/v1.0/user

请求方式:GET

后端代码编写

大致流程:

  • 获取用户id
  • 根据用户id查询数据库
  • 将查询的结果返回

代码

# profile.py

@api.route('/user', methods=['GET'])
@login_required
def get_user_profile():
    """个人主页中获取用户信息
    包括:用户头像,手机号,用户名
    要求:json格式
    """
    # 获取用户id
    user_id = g.user_id

    # 根据用户id查询该用户的信息
    try:
        user = User.query.get(user_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='获取用户信息失败')

    # 判断获取的user是否为空
    if user is None:
        jsonify(errno=RET.NODATA, errmsg='无效操作')

    return jsonify(errno=RET.OK, errmsg='OK', data=user.to_dict())
# models.py

class User(BaseModel, db.Model):
    ...
    def to_dict(self):
        """
        将数据转换后字典
        :return: 字典
        """
        user_dict = {
            "user_id": self.id,
            "name": self.name,
            "mobile": self.mobile,
            "avatar": constants.QINIU_URL_DOMAIN + self.avatar_url if self.avatar_url else "",
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:S")
        }
        return user_dict

前端代码编写

# my.html

<div class="menu-content">
     <img id="user-avatar" src="">
     <div class="menu-text">
         <h3>用户名:<span id="user-name"></span></h3>
         <h5>手机号:<span id="user-mobile"></span></h5>
     </div> 
</div>
// my.js


$(document).ready(function(){
    $.get('/api/v1.0/user', function (resp) {
        // 判断用户是否登陆
        if (resp.errno == '4101') {
            location.href = '/login.html';
        } else if (resp.errno == '0') {
            // 查新到数据,展示在前台
            $('#user-name').html(resp.data.name);
            $('#user-mobile').html(resp.data.mobile);
            if (resp.data.avatar) {
                $('#user-avatar').attr('src', resp.data.avatar);
            }
        }
    }, "json");
});

个人信息修改界面的完善

个人信息的显示

在个人主页点击修改进入该界面,profile.html

如果没有头像和用户名,则不显示,否则显示,如下图所示,

url:127.0.0.1:5000/api/v1.0/user

请求方式:GET

前端代码编写

# profile.html

<li>
    <div class="menu-title">
        <h3>头像</h3>
    </div>
    <div class="menu-content">
        <img id="user-avatar" src="">
        <div class="menu-text">
            <form id="form-avatar" enctype="multipart/form-data">
                选择头像:<input type="file" accept="image/*" name="avatar">
                <input type="submit" class="btn btn-success" value="上传">
            </form>
        </div> 
    </div>
</li>
<li>
    <div class="menu-title">
        <h3>用户名</h3>
    </div>
    <div class="menu-content">
        <form id="form-name">
            <input type="text" name="name" id="user-name">
            <input type="submit" class="btn btn-success" value="保存">
        </form>
        <div class="error-msg"><i class="fa fa-exclamation-circle"></i>用户名已存在,请重新设置</div>
    </div>
</li>
# profile.js

// 获取用户信息
    $.get('/api/v1.0/user', function (resp) {
        if (resp.errno == '4104') {
            // 未登录,跳转到登陆界面
            location.href = '/login.html'
        } else if(resp.errno == '0') {
            // 有获取到用户信息
            $('#user-name').val(resp.data.name);
            if (resp.data.avatar) {
                $('#user-avatar').attr('src', resp.data.avatar);
            }
        }
    }, "json");

用户名的修改操作

从新输入用户名,点击保存,更新用户名

url:127.0.0.1:5000/api/v1.0/users/name

请求方式:PUT

后端代码编写

大致流程:

  • 获取用户id
  • 获取提交的用户名
  • 判断用户名是否为空
  • 保存到数据库中
  • 更新session中的name值
  • 返回结果
# profile.py

@api.route('/users/name', methods=['PUT'])
@login_required
def change_user_name():
    """修改用户名"""
    user_id = g.user_id
    req_data = request.get_json()

    # 判断参数的完整性
    if req_data is None:
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')

    # 获取要修改的name值
    name = req_data.get('name')

    # 判断是否为空
    if not name:
        return jsonify(errno=RET.PARAMERR, errmsg='用户名不能为空')

    # 保存用户名到数据库(更新操作),同时利用数据库的唯一索引判断是否重复
    try:
        User.query.filter_by(id=user_id).update({"name": name})
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='设置用户名错误')

    # 更新session中的name值
    session['name'] = name

    # 返回结果
    return jsonify(errno=RET.OK, errmsg='修改成功')

前端代码编写

// profile.js

$(document).ready(function () {

    ...

    // 修改用户名
    $('#form-name').submit(function (e) {
        // 阻止form表单的默认行为
        e.preventDefault();
        // 获取name值
        var name = $('#user-name').val();
        // 判断用户名是否为空
        if (!name) {
            alert('用户名不能为空!');
            return
        }
        // ajax 提交用户名
        $.ajax({
            url: '/api/v1.0/users/name',
            data: JSON.stringify({'name': name}),
            type: 'PUT',
            contentType: 'application/json',
            dataType: 'json',
            headers: {
                "X-CSRFToken": getCookie('csrf_token')
            },
            success: function (data) {
                if (data.errno == '0') {
                    $('.error-msg').hide();
                    showSuccessMsg();
                } else if (data.errno == '4001') {
                    $('.error-msg').show();
                } else if (data.errno == '4101') {
                    location.href = '/login.html';
                }
            }
        });

    });
});

实名信息认证

实名信息的显示

如果没有进行过实名认证的话,显示可以输入与按钮

如果已经提交认证信息,则显示实名信息,并不可修改,同时隐藏提交按钮

url:127.0.0.1:5000/api/v1.0/users/auth

请求方式:GET

后端代码编写

大致流程:

  • 获取用户id
  • 获取用户信息
  • 返回结果
# profile.py

@api.route('/users/auth', methods=['GET'])
@login_required
def get_user_auth():
    """获取用户的实名认证信息"""
    user_id = g.user_id

    try:
        user = User.query.get(user_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='获取用户实名信息失败')

    if user is None:
        return jsonify(errno=RET.NODATA, errmsg='无效操作')

    return jsonify(errno=RET.OK, errmsg='OK', data=user.auto_to_dict())
# models.py

class User(...):
    ...

    def auto_to_dict(self):
        """
        将实名信息转换成字典
        :return: 字典
        """
        auto_dict = {
            "user_id": self.id,
            "real_name": self.real_name,
            "id_card": self.id_card
        }
        return auto_dict

前端代码编写

// auth.js

$(document).ready(function () {
    // 查询用户的实名信息
    $.get('/api/v1.0/users/auth', function (resp) {
        // 判断是否登陆,4101表示未登录
        if(resp.errno == '4101'){
            location.href = '/login.html'
        }else if(resp.errno == '0') {
            // 已经登陆,如果返回的real_name与id_card不为null,表示用户有填写实名信息
            if (resp.data.real_name && resp.data.id_card){
                // 将实名信息填写到页面中,并不再可以修改,同时隐藏按钮
                $('#real-name').val(resp.data.real_name);
                $('#id-card').val(resp.data.id_card);
                $('#real-name').prop('disabled', true);
                $('#id-card').prop('disabled', true);
                $('#form-auth>input[type=submit]').hide();
            }
        }
    }, "json");
});

实名信息认证

后端代码编写

请求方式:POST

大致流程:

  • 获取用户id
  • 获取认证信息
  • 判断认证信息的完整性
  • 保存到数据库中
  • 返回结果
# profile.py

@api.route('/users/auth', methods=['POST'])
@login_required
def set_user_auth():
    """保存实名认证信息
    包括:真实名、身份证号
    要求:json格式
    """
    # 获取用户id
    user_id = g.user_id

    # 获取实名信息
    req_data = request.get_json()

    if not req_data:
        return jsonify(errno=RET.PARAMERR, errmsg='参数错误')

    real_name = req_data.get('real_name')
    id_card = req_data.get('id_card')

    # 判断参数的完整性
    if not all([real_name, id_card]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')

    try:
        User.query.filter_by(id=user_id, real_name=None, id_card=None).update({"real_name": real_name, "id_card": id_card})
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='保存实名信息失败')

    # 返回结果
    return jsonify(errno=RET.OK, errmsg='OK')

前端代码编写

// auth.js

$(document).ready(function () {
    // 查询用户的实名信息
    ...

    // 用户实名信息的提交行为
    $('#form-auth').submit(function (e) {
        // 阻止表单的默认提交行为
        e.preventDefault();
        // 获取实名信息
        var real_name = $('#real-name').val();
        var id_card = $('#id-card').val();
        // 判断是否为空
        if (real_name == "" || id_card == ""){
            $('.error-msg').show();
        }
        // 将数据转换成json格式
        var data = {
            "real_name": real_name,
            "id_card": id_card
        };
        var json_data = JSON.stringify(data);
        // ajax提交,保存实名认证信息
        $.ajax({
            url: '/api/v1.0/users/auth',
            data: json_data,
            dataType: 'json',
            type: 'post',
            contentType: 'application/json',
            headers: {
                'X-CSRFToken': getCookie('csrf_token')
            },
            success: function (resp) {
                if (resp.errno == '0'){
                    $('.error-msg').hide();
                    showSuccessMsg();
                    $('#real-name').prop('disabled', true);
                    $('#id-card').prop('disabled', true);
                    $('#form-auth>input[type=submit]').hide();
                }else{
                    alert(resp.errmsg);
                }
            }
        });

    });
});

城区信息

后端代码编写

# api/houses.py
from flask import current_app, jsonify

from . import api
from ihome.models import Area
from ihome.utils.response_code import RET


@api.route('/areas')
def get_area_info():
    """获取区域信息"""
    # 查新数据库
    try:
        area_li = Area.query.all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库异常')
    area_dict_li = []
    for area in area_li:
        area_dict_li.append(area.to_dict())
    return jsonify(errno=RET.OK, errmsg='OK', data=area_dict_li)
# ihome/models.py
class Area(BaseModel, db.Model):
    """城区"""

    __tablename__ = "ih_area_info"

    id = db.Column(db.Integer, primary_key=True)  # 区域编号
    name = db.Column(db.String(32), nullable=False)  # 区域名字
    houses = db.relationship("House", backref="area")  # 区域的房屋

    def to_dict(self):
        """将对象转换成字典"""
        area_dict = {
            "aid": self.id,
            "aname": self.name
        }
        return area_dict

postman测试

启动项目,打开postman,输入获取城区信息的url,请求方式为get

 

缓存数据库

由于城区信息会频繁的访问,所以考虑将城区信息取出后保存到redis中,这样再取时先从redis中取,如果redis中没有,在从mysql数据库中取。

大致流程:

  • 从redis中获取城区信息
    • 有,直接返回
    • 没有,继续下一步
  • 从mysql数据库中获取城区信息
  • 将取出的数据转换成json格式
  • 将json数据保存到redis中
  • 返回结果
import json

from flask import current_app, jsonify

from . import api
from ihome.models import Area
from ihome.utils.response_code import RET
from ihome import db, redis_store, constants


@api.route('/areas')
def get_area_info():
    """获取区域信息"""

    # 从redis中获取数据
    try:
        resp_json = redis_store.get('area_info')
    except Exception as e:
        current_app.logger.error(e)
    else:
        if resp_json is not None:
            current_app.logger.info('hide redis area_info')
            return resp_json, 200, {"Contant-Type": 'application/json'}
    # 查新数据库
    try:
        area_li = Area.query.all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库异常')
    area_dict_li = []
    for area in area_li:
        area_dict_li.append(area.to_dict())

    # 将数据转换为json格式
    resp_dict = dict(errno=RET.OK, errmsg='OK', data=area_dict_li)
    resp_json = json.dumps(resp_dict)

    # 将数据保存到redis中
    try:
        redis_store.setex('area_info', constants.AREA_INFO_REDIS_CACHE_EXPIRE, resp_json)
    except Exception as e:
        current_app.logger.error(e)

    return resp_json, 200, {"Contant-Type": 'application/json'}

前端代码编写

# newhouse.hmtl

<label for="area-id">所在城区</label>
<select class="form-control" id="area-id" name="area_id">

</select>
<script type="text/html" id="areas-tmpl">
    {{ each areas as area }}
    <option value="{{ area.aid }}">{{ area.aname }}</option>
    {{ /each }}
</script>

<script src="/static/js/template.js"></script>
// newhouse.js

$(document).ready(function(){
    $.get('/api/v1.0/areas', function (resp) {
        if (resp.errno == '0'){
            var areas = resp.data;
            // for(var i=0; i<areas.length; i++){
            //     var area = areas[i];
            //     // var option = '<option value="'+ area.aid +'">'+ area.aname +'</option>';
            //     $('#area-id').append('<option value="'+ area.aid +'">'+ area.aname +'</option>');
            // }
            var _html = template("areas-tmpl", {"areas": areas});
            $('#area-id').html(_html);
        }else{
            alert(resp.errmsg);
        }
    }, "json");
});

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秒不可闫M先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值