Flask项目之手机端租房网站的实战开发(十三)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!
接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/86599482
目录
一丶保存订单后端接口编写
1.分析:当用户点击房屋图片进入房间信息页面时,在页面最下面会出现即可预定功能按钮(左图),当用户点击预定时,即跳转到预定页面(右图),在该页面中,首选是获取用户点击的房屋信息显示到此页面上,然后需要用户选择入住的时间和离开的时间,当用户选择完时间后那么在界面左下角即显示出订单的价格,点击提交订单后,此时需要从后端来判断此房间在用户选择入住离开期间有没有冲突订单,如果有则提示用户房屋被抢订,重新选择日期的一个提示,如果提交订单成功,则在我的订单中显示出该订单,这是整个业务逻辑
2.逻辑编写如下
- step1 在api_v1.0目录下创建orders.py模块,用于编写订单相关的接口,并在__init__.py模块中导入此模块
- step2 定义路由接口
@api.route("/orders", methods=["POST"])
@login_required
def save_order():
"""保存用户的订单"""
pass
- step3 获取用户id
user_id = g.user_id
- step4 获取前端发送的请求参数
order_data = request.get_json()
- step5 校验参数
if not order_data:
return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
- step6 获取用户预订的房屋编号,入住时间以及离开时间
house_id = order_data.get("house_id")
start_date_str = order_data.get("start_date")
end_date_str = order_data.get("end_date")
- step7 校验参数完整性
if not all([house_id, start_date_str, end_date_str]):
return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")
- step8 检查日期格式
try:
# 将str格式的日期数据转换成datetime格式的日期数据
start_date = datetime.strptime(start_date_str, "%Y-%m-%d")
end_date = datetime.strptime(end_date_str, "%Y-%m-%d")
assert start_date <= end_date #使用断言就行判断
# 计算预订的天数
days = (end_date-start_date).days + 1
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.PARAMERR, errmsg="日期格式不正确")
- step9 查询用户预订的房屋是否存在
try:
house = House.query.get(house_id)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="获取房屋信息失败")
- step10 判断房屋是否存在
if not house:
return jsonify(errno=RET.NODATA, errmsg="房屋不存在")
- step11 判断房东预订的房屋是不是自己的发布的房屋
if user_id == house.user_id:
return jsonify(errno=RET.ROLEERR, errmsg="不能预订自己发布的房屋")
- step12 检查用户预订的时间内,房屋没有被别人下单
try:
# 查询时间冲突的订单数 select count(*) from ih_order_info where ()
count = Order.query.filter(Order.house_id == house_id, Order.begin_date <= end_date, Order.end_date >= start_date).count()
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="系统繁忙,请稍候重试")
- step13 如果查询的订单冲突数大于0,则说明房屋在用户预订时间内,已被他人预订
if count > 0:
return jsonify(errno=RET.DATAERR, errmsg="房屋已被预订")
- step14 计算订单总额
amount = house.price * days
- step15 保存订单数据
order = Order(
house_id=house_id,
user_id=user_id,
begin_date=start_date,
end_date=end_date,
days=days,
house_price=house.price,
amount=amount
)
- step16 将订单数据提交到数据库中,并返回正确响应数据
try:
db.session.add(order)
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", data={"order_id": order.id})
二丶预订页面前端编写以及接口测试
1.在booking.js中进行如下编写
- step1 首先当页面加载完时,则判断用户是否登录
$.get("/api/v1.0/session", function(resp) {
if ("0" != resp.errno) {
location.href = "/login.html";
}
}, "json");
- step2 获取详情页面要展示的房屋编号
var queryData = decodeQuery();
var houseId = queryData["id"];
- step3 获取房屋的基本信息
$.get("/api/v1.0/houses/" + houseId, function(resp){
if (0 == resp.errno) {
$(".house-info>img").attr("src", resp.data.house.img_urls[0]);
$(".house-text>h3").html(resp.data.house.title);
$(".house-text>p>span").html((resp.data.house.price/100.0).toFixed(0));
}
});
- step4 提交订单
$(".submit-btn").on("click", function(e) {
if ($(".order-amount>span").html()) {
$(this).prop("disabled", true);
var startDate = $("#start-date").val();
var endDate = $("#end-date").val();
var data = {
"house_id":houseId,
"start_date":startDate,
"end_date":endDate
};
$.ajax({
url:"/api/v1.0/orders",
type:"POST",
data: JSON.stringify(data),
contentType: "application/json",
dataType: "json",
headers:{
"X-CSRFTOKEN":getCookie("csrf_token"),
},
success: function (resp) {
if ("4101" == resp.errno) {
location.href = "/login.html";
} else if ("4004" == resp.errno) {
showErrorMsg("房间已被抢定,请重新选择日期!");
} else if ("0" == resp.errno) {
location.href = "/orders.html";
}
}
});
}
});
2.测试
- step1 在房屋信息页(左图),点击即可预定后成功跳转到预定界面(右图),并成功显示预定房屋的信息
- step2 在预定房屋界面,选择入住时间以及离开时间后,左下角则成功显示正确的订单总额(左图),当点击提交订单成功后,则跳转到我的订单页面(右图),因为此页面接口未编写,所以啥都没有属于正常情况
- step3 此时查看数据库ih_order_info表,则显示我们成功提交的订单信息,此功能测试成功
三丶订单模块(我的订单)后端接口编写
1.分析:第一当用户成功提交订单后,则会跳转到我的订单页面,此时在这个页面就应该显示出用户刚才预定房屋的订单情况,第二就是需要对角色进行一个判断,如果是下单人那么在我的订单中查看订单,如果是房东那么就在客户订单中,查看别人预定我发布的房屋的订单,无论是哪种情况,对于后端来说都是查询数据库订单信息情况而已,所以这两个功能可以用一个查询订单接口在后端进行实现
2.说明:之所以不管哪种角色在我的爱家页面都出现这两个有关订单的功能(我的订单和客户订单),那是因为对于任何注册网站的用户来说,我既可以订房,也可以发布房源,即一个账号可以切换成两种角色
3.逻辑编写
- step1 定义接口路由
# /api/v1.0/user/orders?role=(custom/landlord)
@api.route("/user/orders", methods=["GET"])
@login_required
def get_user_orders():
"""查询用户的订单信息"""
pass
- step2 获取用户id
user_id = g.user_id
- step3 获取前端请求数据中角色role,如果没有则默认为空字符串
role = request.args.get("role", "")
- step4 获取订单数据
try:
# 以房东的身份在数据库中查询自己发布过的房屋
if "landlord" == role:
houses = House.query.filter(House.user_id == user_id).all()
# 通过列表生成式方式保存房东名下的所有房屋的id
houses_ids = [house.id for house in houses]
# 在Order表中查询预定了自己房子的订单,并按照创建订单的时间的倒序排序,也就是在此页面显示最新的订单信息
orders = Order.query.filter(Order.house_id.in_(houses_ids)).order_by(Order.create_time.desc()).all()
else:
# 以房客的身份查询订单,则查询的是我的订单
orders = Order.query.filter(Order.user_id == user_id).order_by(Order.create_time.desc()).all()
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="获取订单信息失败")
- step5 在models.py模块Order类中构建to_dict方法,用于将详细信息转换为字典数据
def to_dict(self):
"""将订单信息转换为字典数据"""
order_dict = {
"order_id": self.id,
"title": self.house.title,
"img_url": constants.QINIU_URL_DOMAIN + self.house.index_image_url if self.house.index_image_url else "",
"start_date": self.begin_date.strftime("%Y-%m-%d"),
"end_date": self.end_date.strftime("%Y-%m-%d"),
"ctime": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
"days": self.days,
"amount": self.amount,
"status": self.status,
"comment": self.comment if self.comment else ""
}
- step6 订单存在则将订单对象orders转换成字典数据
orders_dict_list = []
if orders:
for order in orders:
orders_dict_list.append(order.to_dict())
- step7 最后向前端返回正确响应数据
return jsonify(errno=RET.OK, errmsg="OK", data={"orders": orders_dict_list})
四丶订单模块(我的订单)前端编写
1.我的订单orders.js中进行如下编写,需注意的是当客户预定的房间后,会引导到支付链接去
// 查询房客订单
$.get("/api/v1.0/user/orders?role=custom", function(resp){
if ("0" == resp.errno) {
$(".orders-list").html(template("orders-list-tmpl", {orders:resp.data.orders}));
$(".order-pay").on("click", function () {
var orderId = $(this).parents("li").attr("order-id");
$.ajax({
url: "/api/v1.0/orders/" + orderId + "/payment",
type: "post",
dataType: "json",
headers: {
"X-CSRFToken": getCookie("csrf_token"),
},
success: function (resp) {
if ("4101" == resp.errno) {
location.href = "/login.html";
} else if ("0" == resp.errno) {
// 引导用户跳转到支付宝连接
location.href = resp.data.pay_url;
}
}
});
});
2.在orders.html中进行如下编写
<script id="orders-list-tmpl" type="text/html">
{{if orders}}
{{each orders as order}}
<li order-id={{order.order_id}}>
<div class="order-title">
<h3>订单编号:{{order.order_id}}</h3>
{{ if "WAIT_COMMENT" == order.status }}
<div class="fr order-operate">
<button type="button" class="btn btn-success order-comment" data-toggle="modal" data-target="#comment-modal">发表评价</button>
</div>
{{ else if "WAIT_PAYMENT" == order.status }}
<div class="fr order-operate">
<button type="button" class="btn btn-success order-pay">去支付</button>
</div>
{{/if}}
</div>
<div class="order-content">
<img src="{{order.img_url}}">
<div class="order-text">
<h3>{{order.title}}</h3>
<ul>
<li>创建时间:{{order.ctime}}</li>
<li>入住日期:{{order.start_date}}</li>
<li>离开日期:{{order.end_date}}</li>
<li>合计金额:¥{{(order.amount/100.0).toFixed(0)}}(共{{order.days}}晚)</li>
<li>订单状态:
<span>
{{if "WAIT_ACCEPT" == order.status}}
待接单
{{else if "WAIT_PAYMENT" == order.status}}
待支付
{{else if "WAIT_COMMENT" == order.status}}
待评价
{{else if "COMPLETE" == order.status}}
已完成
{{else if "REJECTED" == order.status}}
已拒单
{{/if}}
</span>
</li>
{{if "COMPLETE" == order.status}}
<li>我的评价: {{order.comment}}</li>
{{else if "REJECTED" == order.status}}
<li>拒单原因: {{order.comment}}</li>
{{/if}}
</ul>
</div>
</div>
</li>
{{/each}}
{{else}}
暂时没有订单。
{{/if}}
</script>
五丶我的订单功能测试
1.登录18022222222(Hellotaogang)账户后,直接进入我的订单页面,成功显示我的订单信息,如下
2.以客户的角色进行预定房间,选择锦江区,价格由高到低,选择最贵的房间
3.进入房间信息后,点击即可预定(左图),然后提交成功后跳转到我的订单页(右图),成功按照最新预定时间进行排序显示
4.查看数据库ih_user_profile用户信息表以及ih_order_info订单信息表,当前的所有订单都是由18022222222(Hellotaogang)账号进行的预定
5.现在博主登录18033333333(张三)账号进行测试,测试房东能不能预定自己发布的房屋(刷单)
- step1 首先在数据中查看张三发布了哪些房屋
- step2 这里对house_id为10的房屋进行预定,也就是至朴大床房进行预定,结果发现根本没有即可预定按钮(左图),反之对house_id为8的商务套房进行预定,如果成功显示即可预定功能按钮(右图),那么说明编写的代码逻辑没有任何问题
6.上一篇博客中有一个搜索条件未进行测试,因为当时并没有编写订单模块接口,所以无法查询到冲突订单,现在我使用18111111111(taogang123)账号进行相同房间时间冲突为条件进行搜索测试
- step1 根据数据库订单表以及房屋信息表,获取Hellotaogang账号的订单信息以及对应的房屋信息
- step2 根据获取的信息来进行冲突订单搜索条件测试,金牛区房屋id为13的云篆单间入住时间为2019-01-27到2019-01-30的订单已经被Hellotaogang账号预定,无法预定则表示代码逻辑正确
- step3 在主页进行条件搜索时,则不显示冲突订单中房屋信息
六丶订单模块(客户订单)后端接口编写
1.分析:当房东进入客户订单后,即显示出该房东的房屋被客户预定的订单信息,在每个订单上都会有接单以及拒单的功能按钮,不管是接单还是拒单都是改变订单的一个状态,只是房东在选择拒单时必需填写拒绝原因,所以这关于接单和拒单这两个功能接口可以进行复用
2.接口逻辑编写
- step1 定义路由接口,需从前端请求中获取订单编号,使用PUT方式
@api.route("/orders/<int:order_id>/status", methods=["PUT"])
@login_required
def accept_reject_order(order_id):
"""接单拒单"""
pass
- step2 获取用户id
user_id = g.user_id
- step3 获取请求参数
req_data = request.get_json()
- step4 校验参数
if not req_data:
return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
- step5 获取前端用户请求为接单还是拒单,关键字action
action = req_data.get("action")
- step6 判断action参数的值在不在accept接单和reject拒单之间
if action not in ("accept", "reject"):
return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
- step7 在数据库中根据订单号查询订单状态为等待接单状态的订单
try:
order = Order.query.filter(Order.id == order_id, Order.status == "WAIT_ACCEPT").first()
# 获取order订单对象中的house对象
house = order.house
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="无法获取订单数据")
# 如果order对象不存在或者订单中的房屋id不等于用户id 则说明房东在修改不属于自己房屋订单
if not order or house.user_id != user_id:
return jsonify(errno=RET.REQERR, errmsg="操作无效")
- step8 房东选择接单,则对应订单状态为等待评论,拒单则需房东填写拒单的原因
if action == "accept": # 接单
order.status = "WAIT_PAYMENT"
elif action == "reject": # 拒单
reason = req_data.get("reason")
if not reason:
return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
order.status = "REJECTED"
order.comment = reason
- step9 将订单修改后的对象提交到数据库
try:
db.session.add(order)
db.session.commit()
except Exception as e:
current_app.logger.error(e)
db.session.rollback()
return jsonify(errno=RET.DBERR, errmsg="操作失败")
- step10 返回正确响应,因为接口逻辑是在数据库的修改以及查询,所以不需要向前端返回数据
return jsonify(errno=RET.OK, errmsg="OK")
七丶订单模块(客户订单)前端编写以及接口测试
1.在客户订单页lorders.js中进行如下编写
- step1 查询房东的订单
$.get("/api/v1.0/user/orders?role=landlord", function(resp){
if ("0" == resp.errno) {
$(".orders-list").html(template("orders-list-tmpl", {orders:resp.data.orders}));
$(".order-accept").on("click", function(){
var orderId = $(this).parents("li").attr("order-id");
$(".modal-accept").attr("order-id", orderId);
});
- step2 接单处理
$(".modal-accept").on("click", function(){
var orderId = $(this).attr("order-id");
$.ajax({
url:"/api/v1.0/orders/"+orderId+"/status",
type:"PUT",
data:'{"action":"accept"}',
contentType:"application/json",
dataType:"json",
headers:{
"X-CSRFTOKEN":getCookie("csrf_token"),
},
success:function (resp) {
if ("4101" == resp.errno) {
location.href = "/login.html";
} else if ("0" == resp.errno) {
$(".orders-list>li[order-id="+ orderId +"]>div.order-content>div.order-text>ul li:eq(4)>span").html("已接单");
$("ul.orders-list>li[order-id="+ orderId +"]>div.order-title>div.order-operate").hide();
$("#accept-modal").modal("hide");
}
}
})
});
$(".order-reject").on("click", function(){
var orderId = $(this).parents("li").attr("order-id");
$(".modal-reject").attr("order-id", orderId);
});
- step3 拒单处理
$(".modal-reject").on("click", function(){
var orderId = $(this).attr("order-id");
var reject_reason = $("#reject-reason").val();
if (!reject_reason) return;
var data = {
action: "reject",
reason:reject_reason
};
$.ajax({
url:"/api/v1.0/orders/"+orderId+"/status",
type:"PUT",
data:JSON.stringify(data),
contentType:"application/json",
headers: {
"X-CSRFTOKEN":getCookie("csrf_token")
},
dataType:"json",
success:function (resp) {
if ("4101" == resp.errno) {
location.href = "/login.html";
} else if ("0" == resp.errno) {
$(".orders-list>li[order-id="+ orderId +"]>div.order-content>div.order-text>ul li:eq(4)>span").html("已拒单");
$("ul.orders-list>li[order-id="+ orderId +"]>div.order-title>div.order-operate").hide();
$("#reject-modal").modal("hide");
}
}
});
})
2.在lorders.html中进行如下编写
<script id="orders-list-tmpl" type="text/html">
{{if orders}}
{{each orders as order}}
<li order-id={{order.order_id}}>
<div class="order-title">
<h3>订单编号:{{order.order_id}}</h3>
{{ if "WAIT_ACCEPT" == order.status }}
<div class="fr order-operate">
<button type="button" class="btn btn-success order-accept" data-toggle="modal" data-target="#accept-modal">接单</button>
<button type="button" class="btn btn-danger order-reject" data-toggle="modal" data-target="#reject-modal">拒单</button>
</div>
{{/if}}
</div>
<div class="order-content">
<img src="{{order.img_url}}">
<div class="order-text">
<h3>{{order.title}}</h3>
<ul>
<li>创建时间:{{order.ctime}}</li>
<li>入住日期:{{order.start_date}}</li>
<li>离开日期:{{order.end_date}}</li>
<li>合计金额:¥{{(order.amount/100.0).toFixed(0)}}(共{{order.days}}晚)</li>
<li>订单状态:
<span>
{{if "WAIT_ACCEPT" == order.status}}
待接单
{{else if "WAIT_COMMENT" == order.status}}
待评价
{{else if "COMPLETE" == order.status}}
已完成
{{else if "REJECTED" == order.status}}
已拒单
{{/if}}
</span>
</li>
{{if "COMPLETE" == order.status}}
<li>我的评价: {{order.comment}}</li>
{{else if "REJECTED" == order.status}}
<li>拒单原因: {{order.comment}}</li>
{{/if}}
</ul>
</div>
</div>
</li>
{{/each}}
{{else}}
暂时没有订单。
{{/if}}
</script>
3.测试
- step1 使用18033333333(张三)账号进行此接口测试,账号登录后进入客户订单,成功显示客户预定了我发布的房屋列表信息
- step2 查询数据库ih_order_info订单表,验证是否有4张客户订单,结果显示正确,需要注意的是这里的user_id指的是哪个账号预定的,通过user_id发现用户id为3的用户预定了三间,而用户id为8的预定了一间
- step3 查看数据库ih_user_profile表,查看是user_id =3 和 8 的是哪个账号
- step4 分别登录这两个账号,进入我的订单,如果订单详情和张三客户订单一样,说明代码逻辑完全没问题,左图为Hellotaogang账户,右图为taogang123账户
- step5 接单功能接口测试,切换18033333333(张三)账号,进入客户订单,选择订单编号为1的订单,点击接单出现提示信息(左图),点击确定接单后,则在客户订单页中此编号的订单的状态即变成了已接单状态,而在前端中此订单不在显示出接单和拒单功能按钮,说明代码逻辑正确
- step6 拒单功能接口测试,选择订单编号为3的订单进行测试,当点击拒单时,必须要填写原因(左图),然后点击确定后,则该订单状态为已拒绝,说明代码逻辑没问题
- step7 查看数据库订单状态信息,状态为WAIT_PAYMENT的表示已接单,REJECTED表示已拒单,填写的拒单原因存到comment评论字段,证明代码逻辑完全没问题
- step8 切换到到18022222222(Hellotaogang)客户账号,进入我的订单中,查看18033333333(张三)房东对于订单的接单以及拒单情况,对于只有房东接单的订单才会出现去支付的功能按钮,因为该接口还没有写,所以在这里不进行演示,显示信息与上面测试结果一样,代码逻辑正确
八丶订单评价后端接口编写
1.分析:因为订单评价接口和接单拒单功能接口一样,也是对数据库进行修改操作,所以在定义接口路由的时候请求方式也是选择的是PUT,本来订单评价接口是在支付接口后面才去写的,但因为此接口与拒单接单接口大同小异,所以便一块接着客户订单接口在orders.py中一起写了,需要注意的时这个接口是在订单状态变成待评价时,才能触发这个功能接口进行评价
2.逻辑编写
- step1 定义路由接口
@api.route("/orders/<int:order_id>/comment", methods=["PUT"])
@login_required
def save_order_comment(order_id):
"""保存订单评价信息"""
pass
- step2 获取用户id
user_id = g.user_id
- step3 获取请求参数中的评价信息
req_data = request.get_json()
comment = req_data.get("comment")
- step4 校验参数
if not comment:
return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
- step5 确保用户只能评价自己的订单并且订单处于待评价的状态
try:
order = Order.query.filter(Order.id == order_id, Order.user_id == user_id, Order.status == "WAIT_COMMENT").first()
house = order.house
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="无法获取订单数据")
- step6 查询的订单对象order不存在,则返回错误信息
if not order:
return jsonify(errno=RET.REQERR, errmsg="操作无效")
- step7 构建订单参数,并提交到数据库中
try:
# 将订单的状态设置为已完成
order.status = "COMPLETE"
# 保存订单的评价信息
order.comment = comment
# 将房屋的完成订单数增加1
house.order_count += 1
db.session.add(order)
db.session.add(house)
db.session.commit()
except Exception as e:
current_app.logger.error(e)
db.session.rollback()
return jsonify(errno=RET.DBERR, errmsg="操作失败")
- step8 因为在房屋详情中有会显示订单的评价信息,为了在房屋详情中显示最新的评价信息,所以需要删除redis中该订单对应的房屋的信息,并返回正确响应
try:
redis_store.delete("house_info_%s" % order.house.id)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.OK, errmsg="OK")
3.在order.js中补充处理评论的逻辑
$.ajax({
url:"/api/v1.0/orders/"+orderId+"/comment",
type:"PUT",
data:JSON.stringify(data),
contentType:"application/json",
dataType:"json",
headers:{
"X-CSRFTOKEN":getCookie("csrf_token"),
},
success:function (resp) {
if ("4101" == resp.errno) {
location.href = "/login.html";
} else if ("0" == resp.errno) {
$(".orders-list>li[order-id="+ orderId +"]>div.order-content>div.order-text>ul li:eq(4)>span").html("已完成");
$("ul.orders-list>li[order-id="+ orderId +"]>div.order-title>div.order-operate").hide();
$("#comment-modal").modal("hide");
}
}
});
注:此接口在客户支付订单后,订单状态变成待评价时,才能进行测试
Flask项目之手机端租房网站的实战开发(十三)的更多相关文章
- Flask项目之手机端租房网站的实战开发(三)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(一)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 一丶项目介绍 产品:关于手机移动端的租房网站 角色:在这个产品中用户包括房东与房客 功能:房东可以在这个平台发布自己的房屋,房客可 ...
- Flask项目之手机端租房网站的实战开发(二)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(十四)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(六)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(十一)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(十)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(九)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(八)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(四)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
随机推荐
- java 爬虫在 netbeans 里执行和单独执行结果不一样
在做内容測试的时候.发现我的爬虫(前些文章略有提及)在 netbeans 里面可以成功爬取网页内容,而单独执行时,给定一个 url,爬到的网页却与在浏览器里面打开 url 的网页全然不一样,这是一个非 ...
- hdu2795Billboard(线段树,找第一个大于w的点)
Billboard Time Limit: 20000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- nginx 11个过程
nginx在处理每一个用户请求时,都是按照若干个不同的阶段依次处理的,与配置文件上的顺序没有关系,详细内容可以阅读<深入理解nginx:模块开发与架构解析>这本书,这里只做简单介绍: 1. ...
- WebServic调用天气预报服务
在项目开发中,我们除了发布WebService提供客户调用外,也经常需要调用一些客户或者第三方的WebService服务,这里就通过一个Demo来演示调用一个第三方的天气预报服务. 1.天气预报服务接 ...
- 洛谷P3355 骑士共存问题
题目描述 在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入 对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置 ...
- OpenSUSE下支持托盘的邮件客户端Sylpheed
在网上搜索了很多客户端想支持系统托盘,发现一个很不错的邮件客户端Sylpheed.设置方式和foxmail很像,最为重要的是支持系统托盘,很方便,默认没有开启,简单设置下:配置->通用首选项-& ...
- js sort()函数 排序问题 var arr =['A-1-5-1','A-1-10-2','A-1-5-5','B-2-3-1','C-4-10-1'], 对这个数组进行排序,想达到的效果是["A-1-5-1", "A-1-5-5", "A-4-10-1", "A-1-10-2", "A-2-3-1"]
先介绍个方法 charCodeAt() 方法可返回指定位置的字符的 Unicode 编码.这个返回值是 0 - 65535 之间的整数. stringObject.charCodeAt(index) ...
- 利用canvas画一个实时时钟
先放一张效果图: 下面是源代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...
- Zabbix钉钉小机器人报警
1.下载钉钉所需要的脚本golang-zabbix-robot-64,浏览器访问https://www.appgao.com/files/192.html: 图一 脚本下载 2.将脚本路径添加到 ...
- 学习《Python数据科学手册》高清中文PDF+高清英文PDF+代码
如果有一定的数据分析与机器学习理论与实践基础,<Python数据科学手册>这本书是绝佳选择. 是对以数据深度需求为中心的科学.研究以及针对计算和统计方法的参考书.很友好实用,结构很清晰.但 ...