Flask项目之手机端租房网站的实战开发(十一)

说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!

接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/86512594

目录

一丶用户房屋管理后端编写

二丶用户房屋管理前端编写

三丶测试用户管理后端接口

四丶主页幻灯片房屋信息后端编写

五丶主页幻灯片房屋信息前端编写

六丶测试主页幻灯片接口和区县信息以及房屋信息缓存

七丶房屋详情页后端编写

八丶房屋详情页前端编写

九丶测试房屋详情页面显示正确数据是否成功


 

一丶用户房屋管理后端编写

1.需求分析:在我的房源界面显示出房东发布的房源信息,在前端中就需要从后端接口中发送获取用户id,房屋标题,图片以及房屋信息,显示在前端页面中

2.逻辑编写

  • step1 在houses.py中定义接口
@api.route("/user/houses", methods=["GET"])
@login_required
def get_user_houses():
    """
    获取房东发布的房源信息
    :return:
    """
    pass
  • step2 获取用户id
user_id = g.user_id
  • step3 通过用户id从数据库USER中获取用户对象,通过user对象来获取用户发布的房屋
try:
    user = User.query.get(user_id)
    houses = user.houses
except Exception as e:
    current_app.logger.error(e)
    return jsonify(errno=RET.DBERR, errmsg="获取数据失败")
  • step4 在models.py中house里面定义一个to_basic_dict方法,将房屋基本信息转换成字典数据
def to_basic_dict(self):
    """将基本信息转换为字典数据"""
    house_dict = {
        "house_id": self.id,
        "title": self.title,
        "price": self.price,
        "area_name": self.area.name,
        "img_url": constants.QINIU_URL_DOMAIN + self.index_image_url if self.index_image_url else "",
        "room_count": self.room_count,
        "order_count": self.order_count,
        "address": self.address,
        "user_avatar": constants.QINIU_URL_DOMAIN + self.user.avatar_url if self.user.avatar_url else "",
        "ctime": self.create_time.strftime("%Y-%m-%d")
    }
    return house_dict
  • step5 将查询到的房屋信息转换成字典数据,添加到定义的houses_list列表中
houses_list = []
for house in houses:
    houses_list.append(house.to_basic_dict())
  • step6 最后返回正确响应数据
return jsonify(errno=RET.OK, errmsg="OK", data={"houses":houses_list})

二丶用户房屋管理前端编写

1.在myhouse.js中通过get请求方式向后端接口发送请求,通过后端返回的正确响应以及data数据,传到前端html中的template模本进行数据显示,如下编写

$.get("/api/v1.0/user/houses", function(resp){
            if ("0" == resp.errno) {
                $("#houses-list").html(template("houses-list-tmpl", {houses:resp.data.houses}));
            } else {
                $("#houses-list").html(template("houses-list-tmpl", {houses:[]}));
            }
        });

2.引入template.js模板,在my.html中进行如下编写

三丶测试用户管理后端接口

1.之前在编写发布房源接口时,已经发布过房源信息了,所以当进入我的房源页面时,就会向后端接口发送请求,获取房源数据,显示在页面上,如下图所示

Flask项目之手机端租房网站的实战开发(十一)_第1张图片

2.查看数据库房屋信息表ih_house_info

Flask项目之手机端租房网站的实战开发(十一)_第2张图片

四丶主页幻灯片房屋信息后端编写

1.分析:首先主页幻灯片上显示的房屋信息,需要在后端定义一个接口,在这个接口中我们需要在数据库中将房屋订单数目最多的5条数据查询出来,展示到主页上,这个需求也是刚开始开发项目的需求,因为主页时用户大量访问的,所以这5条数据需要缓存到redis数据库中,减少我们对数据库的查询

2.逻辑编写(具体实现)

  • step1 定义视图函数,此接口因为是在主页所以不需要用户登录验证
@api.route("/houses/index", methods=["GET"])
def get_house_index():
    """
    获取主页幻灯片房屋信息
    :return:
    """
    pass
  • step2 查询数据库获取房屋订单数目最多的5条数据
try:
    # 查询房屋订单倒序排序并显示5条
    houses = House.query.order_by(House.order_count.desc()).limit(constants.HOME_PAGE_MAX_HOUSES)
except Exception as e:
    current_app.logger.error(e)
    return jsonify(errno=RET.DBERR, errmsg="查询数据失败")
  • step3 判断数据是否存在,不存在则返回异常错误信息
if not houses:
    return jsonify(errno=RET.NODATA, errmsg="无相关数据")
  • step4 将查询到的房屋信息转换成字典数据,添加到定义的houses_list列表中,如过房屋未设置主图片,则跳过
houses_list = []
for house in houses:
    if not house.index_image_url:
        continue
    houses_list.append(house.to_basic_dict())
  • step5 将列表数据转换从json格式的数据,并存到redis数据库中
try:
    json_houses = json.dumps(houses_list)
    redis_store.setex("home_page_data", constants.HOME_PAGE_DATA_REDIS_EXPIRES, json_houses)
except Exception as e:
    current_app.logger.error(e)
  • step6 返回正确响应数据
return '{"errno":"0", "errmsg":"OK", "data":%s}' % json_houses, 200, {"Content-Type":"application/json"}
  • step7 因为第一次是不存在缓存数据的,所以我们在进入函数时,就先从redis中拿取数据
try:
    ret = redis_store.get("home_page_data")
except Exception as e:
    current_app.logger.error(e)
    ret = None
  • step8 此时需要对获取数据进行判断,当获取数据结果不为空时,则返回给前端正确响应数据,不存在时else就在数据库中进行数据查询,再将查询结果写入到redis数据库
# 当ret获取数据结果不为空时,则返回给前端正确响应数据,不存在时else就在数据库中进行数据查询,再将查询结果写入到redis数据库
if ret:
    current_app.logger.info("house index info from redis")
    # 因为redis中保存的是json字符串,所以直接进行字符串拼接返回
    return '{"errno":0, "errmsg":"OK", "data":%s}' % ret, 200, {"Content-Type": "application/json"}
else:
    # 查询数据库获取房屋订单数目最多的5条数据
    try:
        # 查询房屋订单倒序排序并显示5条
        houses = House.query.order_by(House.order_count.desc()).limit(constants.HOME_PAGE_MAX_HOUSES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询数据失败")

五丶主页幻灯片房屋信息前端编写

1.在主页前端index.js中,需要向后端接口发送请求来获取主页幻灯片要展示的房屋信息

// 获取幻灯片要展示的房屋基本信息
$.get("/api/v1.0/houses/index", function(resp){
    if ("0" == resp.errno) {
        $(".swiper-wrapper").html(template("swiper-houses-tmpl", {houses:resp.data}));

        // 设置幻灯片对象,开启幻灯片滚动
        var mySwiper = new Swiper ('.swiper-container', {
            loop: true,
            autoplay: 2000,
            autoplayDisableOnInteraction: false,
            pagination: '.swiper-pagination',
            paginationClickable: true
        });
    }
});

2.在主页页面中选择区县按钮块,需要从后端接口获取区县信息

// 获取区县信息
$.get("/api/v1.0/areas", function(resp){
    if ("0" == resp.errno) {
        $(".area-list").html(template("area-list-tmpl", {areas:resp.data}));
        $(".area-list a").click(function(e){
            $("#area-btn").html($(this).html());
            $(".search-btn").attr("area-id", $(this).attr("area-id"));
            $(".search-btn").attr("area-name", $(this).html());
            $("#area-modal").modal("hide");
        });
    }
});

3.在主页index.html中进行一个模板使用,将后端返回的响应数据显示在模板中,幻灯片部分如下

4.在主页index.html中区县模板,编写如下

六丶测试主页幻灯片接口和区县信息以及房屋信息缓存

1.幻灯片接口

Flask项目之手机端租房网站的实战开发(十一)_第3张图片

2.区县信息显示

 Flask项目之手机端租房网站的实战开发(十一)_第4张图片

3.查看项目运行日志

Flask项目之手机端租房网站的实战开发(十一)_第5张图片 

4.此时查看数据库缓存

Flask项目之手机端租房网站的实战开发(十一)_第6张图片

 七丶房屋详情页后端编写

1.分析:①在房屋详情页面,角色分为房东以及客户,当客户进入时对于前端页面来说需显示预定功能按钮,如是房东角色进入就不展示此功能按钮;②对于角色来说,那么就需要用到user_id了;③尝试从session中去获取用户id,如果存在,说明用户为登录状态,那么将用户id返回给前端,不存在返回user_id = -1

2.逻辑编写

  • step1 创建视图函数,需要前端给后端传递房屋id
@api.route("/houses/", methods=["GET"])
def get_house_detail(house_id):
    """
    获取房屋详情
    :param house_id:
    :return:
    """
    pass
  • step2 从session中尝试获取用户id,没有则赋值-1
user_id = session.get("user_id", "-1")
  • step3 校验house_id, 不存在则返回错误信息提示
if not house_id:
    return jsonify(errno=RET.PARAMERR, errmsg="参数缺失")
  • step4 通过house_id 查询数据库获取房屋对象
try:
    house = House.query.get(house_id)
except Exception as e:
    current_app.logger.error(e)
    return jsonify(errno=RET.DBERR, errmsg="查询数据失败")
  • step5 判断对象是否存在
if not house:
    return jsonify(errno=RET.NODATA, errmsg="房屋不存在")
  • step6 在models.py文件House类中定义to_full_dict方法,用作于将详细信息转换为字典数据;在这个方法里面需要将房屋图片,房屋设施以及评论信息,单独添加到列表中,最后在将该列表以值的方式保存到字典house_dict中
    def to_full_dict(self):
        """将详细信息转换为字典数据"""
        house_dict = {
            "hid": self.id,
            "user_id": self.user_id,
            "user_name": self.user.name,
            "user_avatar": constants.QINIU_URL_DOMAIN + self.user.avatar_url if self.user.avatar_url else "",
            "title": self.title,
            "price": self.price,
            "address": self.address,
            "room_count": self.room_count,
            "acreage": self.acreage,
            "unit": self.unit,
            "capacity": self.capacity,
            "beds": self.beds,
            "deposit": self.deposit,
            "min_days": self.min_days,
            "max_days": self.max_days,
        }

        # 房屋图片
        img_urls = []
        for image in self.images:
            img_urls.append(constants.QINIU_URL_DOMAIN + image.url)
        house_dict["img_urls"] = img_urls

        # 房屋设施
        facilities = []
        for facility in self.facilities:
            facilities.append(facility.id)
        house_dict["facilities"] = facilities

        # 评论信息
        comments = []
        orders = Order.query.filter(Order.house_id == self.id, Order.status == "COMPLETE", Order.comment != None) \
            .order_by(Order.update_time.desc()).limit(constants.HOUSE_DETAIL_COMMENT_DISPLAY_COUNTS)
        for order in orders:
            comment = {
                "comment": order.comment,  # 评论的内容
                "user_name": order.user.name if order.user.name != order.user.mobile else "匿名用户",  # 发表评论的用户
                "ctime": order.update_time.strftime("%Y-%m-%d %H:%M:%S")  # 评价的时间
            }
            comments.append(comment)
        house_dict["comments"] = comments
        return house_dict
  • step7 将查询到的房屋对象转换成字典
try:
    house_data = house.to_full_dict()
except Exception as e:
    current_app.logger.error(e)
    return jsonify(errno=RET.DATAERR, errmsg="数据错误")
  • step8 将房屋详情数据转换成json格式的数据,并存到redis数据库中
json_houses = json.dumps(house_data)
try:
    redis_store.setex("house_info_%s" % house_id, constants.HOUSE_DETAIL_REDIS_EXPIRE_SECOND, json_houses)
except Exception as e:
    current_app.logger.error(e)
  • step9 构造响应数据, 并返回
resp = '{"errno":"0", "errmsg":"OK", "data":{"user_id":%s, "house":%s}}' %(user_id, json_houses), 200, {"Content-Type": "application/json"}
    return resp
  • step10 尝试从redis数据库中获取房屋详情信息, 出现异常则使ret为None,所以需要在进入函数后,那么需要从去数据库中获取房屋详情信息
try:
    ret = redis_store.get("house_info_%s" % house_id)
except Exception as e:
    current_app.logger.error(e)
    ret = None
  • step11 对ret进行判断, 存在不为None 则直接返回正确响应数据即可
if ret:
    current_app.logger.info("house info from redis")
    return '{"errno":"0", "errmsg":"OK", "data":{"user_id":%s, "house":%s}}' % (user_id, ret), 200, {"Content-Type": "application/json"}

八丶房屋详情页前端编写

1.在detail.js文件中

  • step1 定义decodeQuery函数,用作于解析提取url中的查询字符串参数
function decodeQuery(){
    var search = decodeURI(document.location.search);
    return search.replace(/(^\?)/, '').split('&').reduce(function(result, item){
        values = item.split('=');
        result[values[0]] = values[1];
        return result;
    }, {});
}
  • step2 在$(document).ready(function(){}回调函数中,获取详情页面要展示的房屋编号
var queryData = decodeQuery();
var houseId = queryData["id"];
  • step3 获取房屋详细信息
$.get("/api/v1.0/houses/" + houseId, function(resp){
    if ("0" == resp.errno) {
        $(".swiper-container").html(template("house-image-tmpl", {img_urls:resp.data.house.img_urls, price:resp.data.house.price}));
        $(".detail-con").html(template("house-detail-tmpl", {house:resp.data.house}));

        // resp.user_id为访问页面用户,resp.data.user_id为房东
        if (resp.data.user_id != resp.data.house.user_id) {
            $(".book-house").attr("href", "/booking.html?hid="+resp.data.house.hid);
            $(".book-house").show();
        }
        var mySwiper = new Swiper ('.swiper-container', {
            loop: true,
            autoplay: 2000,
            autoplayDisableOnInteraction: false,
            pagination: '.swiper-pagination',
            paginationType: 'fraction'
        });
    }
})

2.在detail.html文件中

  • step1 房屋详情页面中幻灯片房屋信息编写如下
  • step2 房屋标题,房屋地址,房屋详情,配套设施以及评价信息编写如下

九丶测试房屋详情页面显示正确数据是否成功

1.运行项目,在浏览器输入http://127.0.0.1:5000,即进入网站主页,如下图所示

Flask项目之手机端租房网站的实战开发(十一)_第7张图片

2.点击主页任意幻灯片,进入房屋详情页面

Flask项目之手机端租房网站的实战开发(十一)_第8张图片

3.前端房屋完整信息图如下

 Flask项目之手机端租房网站的实战开发(十一)_第9张图片

4.查询数据库中房屋信息表以及设备设施表id和house_id为3的数据与前端页面显示数据进行对比

  • step1 在ih_house_info 房屋信息表中查看id=3的数据

Flask项目之手机端租房网站的实战开发(十一)_第10张图片

  • step2 在ih_house_facility 房屋设备表中,查看house_id为3的设备数据为9条,与前端页面house_id为3的设备信息一致

Flask项目之手机端租房网站的实战开发(十一)_第11张图片

  •  step3 将step2 查询结果与ih_facility_info设备表进行一一对应,然后与第3点前端房屋完整信息图进行对比验证

Flask项目之手机端租房网站的实战开发(十一)_第12张图片

5.查看redis数据库中缓存的房屋详情数据

Flask项目之手机端租房网站的实战开发(十一)_第13张图片

6.查看项目运行日志,显示成功说明本次进入房屋详情页使用的页面数据为缓存数据

Flask项目之手机端租房网站的实战开发(十一)_第14张图片

转载于:https://www.cnblogs.com/cdtaogang/p/10631076.html

你可能感兴趣的:(python,前端,后端)