学习目标
-
掌握房源总数展示功能,能够实现将统计的房源总数在首页中展示
-
掌握最新房源数据展示功能,能够实现将查询的最新房源数据在首页中展示
-
掌握热点房源数据展示功能,能够实现将查询的热点房源数据在首页中展示
-
了解智能提示搜索框的功能说明,能够说出智能提示搜索框的功能逻辑
-
熟悉智能提示搜索框的前端逻辑,能够归纳用户输入和选择的数据如何传递到后端
-
掌握智能提示搜索框的后端逻辑,能够实现根据输入的数据返回相应房源信息的功能
为方便用户能够快速、便捷地查找到心仪的房源,智能租房项目的首页提供了房源总数展示、最新房源展示、热点房源展示和智能搜索这几个功能,其中智能搜索功能可以帮助用户按地区和户型筛选出符合条件的房源。本章将对房源总数展示、最新房源数据展示、热点房源数据展示和智能搜索进行介绍。
7.1 房源总数展示
在智能租房项目中,首页的智能提示搜索框下方展示了当前城市的房源总数。
从图中可以看出,南昌市的房源总数为113318。
房源总数展示功能分功能分析、接口设计、后端实现和渲染模板4个部分实现。
1.功能分析
房源总数展示功能的逻辑比较简单,只需要从数据库中查询房源数据表的总数量,然后将查询结果返回至后端,再由后端渲染到模板文件中即可。房源总数展示功能的实现流程如图所示。
2.接口设计
在设计房源总数接口时,需要明确请求页面、请求方式、请求地址以及返回数据。 请求页面指浏览器发送请求要加载的页面。 请求方式指浏览器向智能租房服务器发送请求或者提交资源时使用的方法。 请求地址指用户在浏览器输入的URL。 返回数据指智能租房服务器接收请求后返回的响应结果。
接口描述 | 说明 |
---|---|
请求页面 | index.html |
请求方式 | GET |
请求地址 | / |
返回数据 | 数字,表示查询的房源总数量,如33980 |
3.后端实现
在项目的根目录下新建文件app.py,在该文件中创建蓝图,并结合房源总数接口定义视图函数。
from flask import Flask, render_template
from setting import Config
import pymysql as ps
app=Flask(__name__)
app.config.from_object(Config)@app.route("/")
def test():# 获得数据库连接con = ps.connect(host="127.0.0.1", port=3306,user="root", password="admin",db="house", charset="utf8")# 获得游标cursor = con.cursor()# 执行查询操作cursor.execute("select count(*) from house_info ")rows = cursor.fetchall()nums=rows[0]return render_template("index.html",num=nums[0])if __name__ == "__main__":app.run(debug=True)
4.渲染模板
在index.html文件中,查询class属性值为area-info的div标签,在该标签下找到房源总数对应的span标签,并将span标签的内容替换为{{ num }}。
<!-- Main Content -->
<div class="container"><!--定位,数量--><div class="row"><div class="col-lg-12"><div class="area-info"><span style="color:#2980b9">当前城市:</span><span style="color:#e74c3c">南昌</span> <span style="color:#2980b9">房源总数:</span><span style="color:#e74c3c">{{ num }}</span></div></div></div><!--当前城市--><div class="row info-line"><!-- 模块1标题 --><div class="col-lg-12 tj-header"><h3>为您为家</h3><div class="describe"><span>为您精准定位,当前城市房源信息</span><span class="float-right"><a href="/list/pattern/1"style="color: #3498db; padding-right: 5px">更多南昌房源</a></span></div></div>
7.2 最新房源数据展示
在智能租房项目中,首页房源总数下方会为用户展示最新房源数据。
从图中可以看出,首页总共展示了6套最新的房源数据,每套房源信息包括房源图片、房源地址、房源户型、房源面积和房源价格。分功能分析、接口设计、后端实现和渲染模板4个部分实现最新房源数据展示的功能。
1.功能分析
最新房源数据为最近新添加的房源数据,若希望在首页中展示最新的房源数据,需要从数据库中查询发布时间较晚的6条房源数据,之后将查询结果返回至后端,由后端渲染到模板文件中即可。
2.接口设计
最新房源数据接口设计如表所示。
接口描述 | 说明 |
---|---|
请求页面 | index.html |
请求方式 | GET |
请求地址 | / |
返回数据 | 房源对象列表 |
因为项目中的房源图片均使用同一张图片,所以返回的数据中无需包含图片名称。
3.后端实现
因为最新房源数据仍然显示在首页上,所以会将最新房源数据展示功能的逻辑代码写到视图函数index()中。在index()函数中增加最新房源数据展示的逻辑代码,具体如下所示。
@app.route("/")
def index():# 查询总房源数量cursor.execute("select count(*) from house_info ")rows = cursor.fetchall()# 总房源数量nums=rows[0]# 查询所有房源中时间最新的6条记录cursor.execute("select * from house_info order by publish_time desc limit 0,6")houses=cursor.fetchall()return render_template("index.html",num=nums[0],house_new_list=houses)
4.渲染模板
为了能够将最新房源数据渲染到首页,这里我们需要将模板变量house_new_list插入到模板文件的指定位置。在index.html文件中,查询class属性值为col-lg-4的所有div标签,保留第一个div标签并删除其他div标签,在保留的div标签外部使用循环结构遍历house_new_list取出每套房源数据,依次将指定标签的内容替换为相应的模板变量。
<!-- 模块1信息展示 -->
{% for house in house_new_list %}
<div class="col-lg-4"><div class="course"><div><a href="/house/{{ house[0] }}"><img class='img-fluid img-box' src="/static/img/house-bg1.jpg"alt=""></a></div><div class="course-info"><span>{{ house[9] }}</span></div><div class="course-info1"><span>{{ house[2] }} - {{ house[3] }}平方米</span><span class="price float-right">¥ {{ house[4] }}</span></div></div>
</div>
{% endfor %}
7.3 热点房源数据展示
智能租房项目中,首页最新房源下方会为用户展示热点房源数据。
首页总共展示了4套热点房源数据,每套房源数据包括房源图片、房源地址、房源户型、房源面积、房源热度和房源价格。
热点房源数据展示功能分功能分析、接口设计、后端实现和渲染模板4个部分实现。
1.功能分析
热点房源数据为浏览量较高的部分数据。热点房源数据展示功能与最新房源数据展示功能类似,不同的是,热点房源数据展示功能用到的房源数据是根据房源的浏览量筛选出来的,而最新房源数据展示功能用到的房源数据是根据房源的发布时间筛选出来的。 若希望在首页中展示热点房源数据,需要从数据库中查询浏览量较高的前4条房源数据,之后将查询结果返回至后端,由后端渲染到模板文件中即可。
2.接口设计
热点房源数据同样在智能租房的首页进行展示,因此请求页面仍然为index.html,请求地址为“/”;由于热点房源数据展示功能的后端逻辑只涉及获取房源数据,所以请求方式为GET;返回的数据为房源对象列表,每套房源包括房源id、房源地址、房源户型、房源面积、房源价格和房源热度。
接口描述 | 说明 |
---|---|
请求页面 | index.html |
请求方式 | GET |
请求地址 | / |
返回数据 | 房源对象列表 |
3.后端实现
热点房源数据展示的后端逻辑:首先从数据库中查询所有的房源数据,并按照浏览量进行降序排列,然后取出位于前4行的房源数据渲染到模板文件中。因为热点房源数据仍然显示在首页上,所以会将热点房源数据展示功能的逻辑代码写到视图函数index()中。
from flask import Flask, render_template
from setting import Config
import pymysql as ps
app=Flask(__name__)
app.config.from_object(Config)
# 获得数据库连接
con = ps.connect(host="127.0.0.1", port=3306,user="root", password="admin",db="house", charset="utf8")
# 获得游标
cursor = con.cursor()@app.route("/")
def index():# 查询总房源数量cursor.execute("select count(*) from house_info ")rows = cursor.fetchall()# 总房源数量nums=rows[0]# 查询所有房源中时间最新的6条记录cursor.execute("select * from house_info order by publish_time desc limit 0,6")houses=cursor.fetchall()# 查询所欲房源中热点房源最高的4条记录cursor.execute("select * from house_info order by page_views desc limit 0,4")pages=cursor.fetchall()return render_template("index.html",num=nums[0],house_new_list=houses,house_hot_list=pages)if __name__ == "__main__":app.run(debug=True)
4.渲染模板
后端代码已经获取了热点房源数据,接下来就需要将热点房源数据渲染到模板文件index.html中。在index.html文件中,查询class属性值为col-lg-3的div标签,保留第一个标签并删除其他标签,在保留的标签外部使用循环结构遍历house_hot_list取出每套房源数据,依次将指定标签的内容替换为指定的模板变量。
<!-- 模块2内容 -->
{% for house in house_hot_list %}
<div class="col-lg-3"><div class="course"><div><a href="/house/{{ house[0] }}"><img class='img-fluid img-box' src="/static/img/house-bg1.jpg"alt=""></a></div><div class="course-info"><span>{{ house[9] }}</span></div><div class="course-info1"><span>{{ house[2] }} - {{ house[3] }}平方米</span><span style="color: #3498db">  <i class="fa fa-heart"aria-hidden="true"> 热度{{ house[16] }}</i></span><span class="price float-right">¥{{ house[4] }}</span></div></div>
</div>
{% endfor %}
7.4 智能搜索
7.4.1 智能搜索功能说明
智能租房中,首页上方展示了一个智能提示搜索框。
1.地区搜索
地区搜索是根据房源所在小区进行搜索,用户在输入框中输入的查询信息可以是地区或小区名称。例如,在智能搜索框中输入“昌平”,此时输入框下方显示了包含“昌平”字眼的提示列表。
当用户输入的查询信息在智能租房中查询不到时,首页顶部会以弹框形式告知用户未找到相关房源。
2.户型搜索
户型搜索是根据房源的户型进行搜索,用户输入的查询信息可以是“x室”、“x厅”或“x室x厅”。例如,将智能提示搜索框中的搜索选项切换成户型搜索,之后在输入框中输入“1室”,此时输入框下方显示了包含“1室”字眼的提示列表。
提示列表罗列了与查询信息“1室”相关的3条房源信息,每条房源信息包括房源户型和该户型包含房源的总套数。值得一提的是,智能提示搜索框除了支持中文搜索之外,也支持英文搜索。
7.4.2 前端逻辑说明
智能租房已经实现了智能搜索的前端逻辑,为了让大家能够快速理解智能搜索的业务逻辑,我们也需要对智能搜索功能的前端逻辑有所了解。智能搜索的前端逻辑代码均位于index.html文件中。
1.定义智能提示搜索框
智能提示搜索框由搜索选项、输入框和提交按钮组成,其中搜索选项由ul标签定义;输入框和提交按钮由form标签定义。
<ul class="nav nav-tabs my-nav-tab" style="margin:15px 0 0 0"><li class="chanle1 active"><span>地区搜索</span></li><li class="chanle2"><span>户型搜索</span></li>
</ul>
输入框和提交按钮的代码如下所示。
<form class="form-inline" role="form" id="my-form" action="/query"><div class="form-group"><label class="sr-only" for="txt">名称</label><input type="text" class="form-control" id="txt" name='addr' placeholder="请输入区域、商圈或小区名开始找房"></div><button type="submit" class="my-btn btn btn-info" id="btn">提交</button><ul id="list" class="list-group"></ul>
</form>
2.选择搜索选项
当用户选择地区搜索或户型搜索选项后,在前端页面中可以看到对应的背景颜色由灰色变为蓝色,输入框的提示信息也跟着发生了变化。 选择搜索选项是通过监听用户点击事件完成的,当触发点击事件后会执行3个操作,分别是给选中选项的标签添加一个类名active、给input标签添加name属性、修改input标签的placholder属性值。
// 由户型搜索切换至地区搜索或者重复点击地区搜索
$(".chanle1").on('click', function () {// 用于地区搜索重复点击的初始化if ($('.chanle1').hasClass('active')) {$(".chanle1").removeClass('active');$("#txt").attr('name', '');$('#txt').attr('placeholder', '')}// 移除户型搜索的样式$(".chanle2").removeClass('active');// 重新设置选中字段和<input>标签的属性$(".chanle1").addClass('active');$("#txt").attr('name', 'addr');$('#txt').attr('placeholder', '请输入区域、商圈或小区名开始找房');
});// 由地区搜索切换至户型搜索或者重复点击户型搜索
$(".chanle2").on('click', function () {// 用于户型搜索重复点击的初始化if ($('.chanle2').hasClass('active')) {$(".chanle2").removeClass('active');$("#txt").attr('name', '');$('#txt').attr('placeholder', '')}// 移除地区搜索的样式$(".chanle1").removeClass('active');// 重新设置选中字段和<input>标签的属性$(".chanle2").addClass('active');$("#txt").attr('name', 'rooms');$('#txt').attr('placeholder', '请输入户型开始找房,例如:1室1厅');
});
3.监听输入框状态
当输入框状态为中文输入法时需要使用compositionstart事件和compositionend事件同步监听,其中compositionstart事件会在中文输入法状态开始输入时触发,compositionend事件会在中文输入法输入完成时触发;当输入框状态为英文输入法时使用input事件同步监听。
// 输入框的书写逻辑
var oTxt = document.getElementById('txt'); // 输入框
var oBtn = document.getElementById('btn'); // 提交按钮
var oList = document.getElementById('list');// 提示列表// 设置锁,true表示锁住输入框,false表示解锁输入框
var cpLock = false;// 中文搜索,监听compositionstart事件,如果触发该事件,就锁住输入框
$('#txt').on('compositionstart', function () {cpLock = true;
});// 中文搜索,监听compositionend事件,如果触发该事件,就解锁输入框
$('#txt').on('compositionend', function () {cpLock = false;var keyWord = oTxt.value;var resultList = searchByIndexOf(keyWord);
});// 英文搜索,监听input事件,用于处理字母搜索
$('#txt').on('input', function () {if (!cpLock) {var keyWord = oTxt.value;var resultList = searchByIndexOf(keyWord);}
});
4.查询关键字
前端获取了关键字后需要向后端发送请求,用于从数据库中查询匹配关键字的内容,并获取查询后的结果。
// 搜索关键字
function searchByIndexOf(keyWord) {$(".my-nav-tab li").each(function (index, element) {if ($(this).hasClass("active")) {var info = $(this).text();data = {"kw": keyWord, "info": info};$.ajax({url: "/search/keyword/",type: 'post',dataType: 'json',data: data,success: function (data) { // {code=0, info=[]}if (data['code'] == 0) {warning_str = '未找到关于' + keyWord + '的房屋信息!';alert(warning_str)}if (data['code'] == 1) { // {code=1, info=[{t_name='字段的名字 例如:东城-xxx-xxxx', num=108},{},{}]}list = data['info'];console.log('search', list);oList.innerHTML = '';var item = null;for (var i = 0; i < 9; i++) {item = document.createElement('li');item.setAttribute("class", "list-group-item li_style");item.setAttribute("title", list[i]['t_name']);li_text = list[i]['t_name'] + '<span class="badge float-right">大约有' + list[i]['num'] + '套房</span>';console.log(li_text);item.innerHTML = li_text;oList.appendChild(item);info_to_txt();}return list;}}});}});
}
7.4.3 后端逻辑实现
智能提示搜索框的前端代码实现了将用户选择的搜索选项和搜索关键字发送到后端,当后端接收到前端发送的请求后,便会根据搜索关键字到数据库中查询相关的房源数据。智能搜索接口设计如下。
接口描述 | 说明 |
---|---|
请求方式 | GET |
请求地址 | / |
请求参数 | {'kw':'xxx','info':'地区搜索'}或者{'kw':'xxx','info':'户型搜索'} |
返回数据 | 房源对象列表 |
智能搜索接口返回的数据是JSON数据。
{"code": 1, "info": [{"t_name": "朝阳-朝阳公园-观湖国际", "num": 100},……]
}
code表示查询成功标志位,支持两种取值0和1,其中0代表查询失败,1代表查询成功;info表示查询到的房源数据,info数组中包含零个或若干个JSON对象,每个JSON对象包含两个键值对,其中键t_name表示查询到的房源所在小区,其类型为字符串;键num表示房源总套数,其类型为整数。
在app.py文件中定义视图函数search_kw(),用于获取用户输入的关键字和用户选择的搜索选项,根据获取的查询条件向数据查询房源数据,并将查询的数据进行返回。
# 关键字搜索
# 完成查询关键字的功能
# 1. 获取前端传递过来的查询参数 {"kw": keyWord, "info": info} kw:查询关键字 info:查询字段 使用request提取参数信息
# 2. 根据查询参数 过滤房源信息 address 包含三里屯的房源
# 3. 使用group_by 对address字段进行分组
# 4. 使用count来统计 相同地址下的房源数量
# 5. 使用order_by 根据房源的数量进行排序 并把它换成降序排序
# 6. 使用limit 获取数据的前9行
# 7. 组装数据 完成前后端的交互
from flask import request,jsonify
@app.route("/search/keyword/",methods=["POST"])
def search_kw():kw = request.form['kw'] # 获取搜索关键字info = request.form['info'] # 获取用户选择的搜索选项if info == '地区搜索':# 根据关键字进行模糊查询,将查询出来的记录按地址进行分组,按数量进行降序排序,取前9条记录sql="SELECT address,COUNT(*) FROM house_info WHERE address LIKE %s GROUP BY address ORDER BY COUNT(*) DESC LIMIT 0,9;"cursor.execute(sql,("%"+kw+"%"))result =cursor.fetchall()if len(result): # 有查询结果data = []for i in result:# 将查询的房源数据添加到data列表中data.append({'t_name': i[0], 'num': i[1]})return jsonify({'code': 1, 'info': data})else: # 没有查询结果return jsonify({'code': 0, 'info': []})if info == '户型搜索':# 根据关键字进行模糊查询,将查询出来的记录按地址进行分组,按数量进行降序排序,取前9条记录sql = "SELECT rooms,COUNT(*) FROM house_info WHERE rooms LIKE %s GROUP BY rooms ORDER BY COUNT(*) DESC LIMIT 0,9;"cursor.execute(sql, ("%"+kw+"%"))result = cursor.fetchall()if len(result):data = []for i in result:data.append({'t_name': i[0], 'num': i[1]})return jsonify({'code': 1, 'info': data})else:return jsonify({'code': 0, 'info': []})
本章小结
本章围绕智能租房项目首页模块的功能进行了介绍,包括房源总数展示、最新房源数据展示、热点房源数据展示和智能搜索。通过学习本章的内容,希望读者能够体会到前端与后端的交互过程,熟练地应用蓝图和视图函数。