文章目录
显示
美食列表展示
Helper.py添加方法:
'''
根据某个字段获取一个dic出来
'''
def getDictFilterField( db_model,select_filed,key_field,id_list ):
ret = {}
query = db_model.query
if id_list and len( id_list ) > 0:
query = query.filter( select_filed.in_( id_list ) )
list = query.all()
if not list:
return ret
for item in list:
if not hasattr( item,key_field ):
break
ret[ getattr( item,key_field ) ] = item
return ret
美食列表接口的添加 Food.py
@route_food.route( "/index" )
def index():
resp_data = {}
req = request.values
page = int(req['p']) if ('p' in req and req['p']) else 1
query = Food.query
if 'mix_kw' in req:
rule = or_(Food.name.ilike("%{0}%".format(req['mix_kw'])), Food.tags.ilike("%{0}%".format(req['mix_kw'])))
query = query.filter( rule )
if 'status' in req and int( req['status'] ) > -1 :
query = query.filter( Food.status == int( req['status'] ) )
if 'cat_id' in req and int( req['cat_id'] ) > 0 :
query = query.filter( Food.cat_id == int( req['cat_id'] ) )
page_params = {
'total':query.count(),
'page_size': app.config['PAGE_SIZE'],
'page':page,
'display':app.config['PAGE_DISPLAY'],
'url': request.full_path.replace("&p={}".format(page),"")
}
pages = iPagination( page_params )
offset = ( page - 1 ) * app.config['PAGE_SIZE']
list = query.order_by( Food.id.desc() ).offset( offset ).limit( app.config['PAGE_SIZE'] ).all()
cat_mapping = getDictFilterField( FoodCat,FoodCat.id,"id",[] )
resp_data['list'] = list
resp_data['pages'] = pages
resp_data['search_con'] = req
resp_data['status_mapping'] = app.config['STATUS_MAPPING']
resp_data['cat_mapping'] = cat_mapping
resp_data['current'] = 'index'
return ops_render( "food/index.html",resp_data )
food/index.html渲染模板
<div class="row">
<div class="col-lg-12">
<form class="form-inline wrap_search">
<div class="row m-t p-w-m">
<div class="form-group">
<select name="status" class="form-control inline">
<option value="-1">请选择状态</option>
{% for tmp_key in status_mapping %}
<option value="{{ tmp_key }}" {% if tmp_key == search_con['status'] %} selected {% endif %}>{{ status_mapping[ tmp_key ] }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<select name="cat_id" class="form-control inline">
<option value="0">请选择分类</option>
{% for tmp_key in cat_mapping %}
<option value="{{ tmp_key }}" {% if tmp_key|string == search_con['cat_id'] %} selected {% endif %} >{{ cat_mapping[ tmp_key].name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<div class="input-group">
<input type="text" name="mix_kw" placeholder="请输入关键字" class="form-control" value="{{ search_con['mix_kw'] }}">
<input type="hidden" name="p" value="{{ search_con['p'] }}">
<span class="input-group-btn">
<button type="button" class="btn btn-primary search">
<i class="fa fa-search"></i>搜索
</button>
</span>
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col-lg-12">
<a class="btn btn-w-m btn-outline btn-primary pull-right" href="{{ buildUrl('/food/set') }}">
<i class="fa fa-plus"></i>美食
</a>
</div>
</div>
</form>
<table class="table table-bordered m-t">
<thead>
<tr>
<th>美食名</th>
<th>分类</th>
<th>价格</th>
<th>库存</th>
<th>标签</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% if list %}
{% for item in list %}
<tr>
<td>{{ item.name }}</td>
<td>{{ cat_mapping[ item.cat_id].name }}</td>
<td>{{ item.price }}</td>
<td>{{ item.stock }}</td>
<td>{{ item.tags }}</td>
<td>
<a href="{{ buildUrl('/food/info') }}?id={{ item.id }}">
<i class="fa fa-eye fa-lg"></i>
</a>
{% if item.status == 1 %}
<a class="m-l" href="{{ buildUrl('/food/set') }}?id={{ item.id }}">
<i class="fa fa-edit fa-lg"></i>
</a>
<a class="m-l remove" href="javascript:void(0);" data="{{ item.id }}">
<i class="fa fa-trash fa-lg"></i>
</a>
{% else %}
<a class="m-l recover" href="javascript:void(0);" data="{{ item.id }}">
<i class="fa fa-rotate-left fa-lg"></i>
</a>
{% endif %}
</td>
</tr>
{% endfor %}
{% else %}
<tr><td colspan="6">暂无数据~~</td></tr>
{% endif %}
</tbody>
</table>
<!--分页代码已被封装到统一模板文件中-->
{% include 'common/pagenation.html' %}
</div>
</div>
详情页面处理
food/Food.py 添加info接口
@route_food.route( "/info" )
def info():
resp_data = {}
req = request.args
id = int(req.get("id", 0))
reback_url = UrlManager.buildUrl("/food/index")
if id < 1:
return redirect( reback_url )
info = Food.query.filter_by( id =id ).first()
if not info:
return redirect( reback_url )
stock_change_list = FoodStockChangeLog.query.filter( FoodStockChangeLog.food_id == id )\
.order_by( FoodStockChangeLog.id.desc() ).all()
resp_data['info'] = info
resp_data['stock_change_list'] = stock_change_list
resp_data['current'] = 'index'
return ops_render( "food/info.html",resp_data )
info.html
<div class="row">
<div class="col-lg-12">
<p class="m-t">美食名:{{ info.name }}</p>
<p>售价:{{ info.price }}</p>
<p>库存总量:{{ info.stock }}</p>
<p>图书标签:{{ info.tags }}</p>
<p>封面图:<img src="{{ buildImageUrl( info.main_image ) }}" style="width: 50px;height: 50px;"></p>
<p>描述:</p>
<p>{{ info.summary | safe }}</p>
<p></p>
</div>
</div>
<div class="tab-pane" id="tab-2">
<table class="table table-striped">
<thead>
<tr>
<th>变更</th>
<th>备注</th>
<th>时间</th>
</tr>
</thead>
<tbody>
{% if stock_change_list %}
{% for item in stock_change_list %}
<tr>
<td>{{ item.unit }}</td>
<td>{{ item.note }}</td>
<td>{{ item.created_time }}</td>
</tr>
{% endfor %}
{% else %}
<tr><td colspan="3">暂无数据~~</td></tr>
{% endif %}
</tbody>
</table>
</div>
删除和编辑功能的实现
food下面創建index.js
;
var food_index_ops = {
init:function(){
this.eventBind();
},
eventBind:function(){
var that = this;
$(".remove").click( function(){
that.ops( "remove",$(this).attr("data") )
});
$(".recover").click( function(){
that.ops( "recover",$(this).attr("data") )
});
$(".wrap_search .search").click( function(){
$(".wrap_search").submit();
});
},
ops:function( act,id ){
var callback = {
'ok':function(){
$.ajax({
url:common_ops.buildUrl("/food/ops"),
type:'POST',
data:{
act:act,
id:id
},
dataType:'json',
success:function( res ){
var callback = null;
if( res.code == 200 ){
callback = function(){
window.location.href = window.location.href;
}
}
common_ops.alert( res.msg,callback );
}
});
},
'cancel':null
};
common_ops.confirm( ( act=="remove" )?"确定删除?":"确定恢复?",callback );
}
};
$(document).ready( function(){
food_index_ops.init();
});
index.html引入js文件
{% block js %}
<script src="{{ buildStaticUrl('/js/food/index.js') }}"></script>
{% endblock %}
Food.py添加ops接口
@route_food.route("/ops",methods=["POST"])
def ops():
resp = { 'code':200,'msg':'操作成功~~','data':{} }
req = request.values
id = req['id'] if 'id' in req else 0
act = req['act'] if 'act' in req else ''
if not id :
resp['code'] = -1
resp['msg'] = "请选择要操作的账号~~"
return jsonify(resp)
if act not in [ 'remove','recover' ]:
resp['code'] = -1
resp['msg'] = "操作有误,请重试~~"
return jsonify(resp)
food_info = Food.query.filter_by( id = id ).first()
if not food_info:
resp['code'] = -1
resp['msg'] = "指定美食不存在~~"
return jsonify(resp)
if act == "remove":
food_info.status = 0
elif act == "recover":
food_info.status = 1
food_info.updated_time = getCurrentDate()
db.session.add(food_info)
db.session.commit()
return jsonify( resp )
统一配置优化
common.js下面的buildPicUrl存在固定的url,如何将配置传递到js里面
common/layout.html
<div class="hidden hidden_layout_wrap">
<input name="domain" value="{{ config.APP.domain }}">
<input name="prefix_url" value="{{ config.UPLOAD.prefix_url }}">
</div>
<script src="{{ buildStaticUrl('/plugins/jquery-2.1.1.js') }}"></script>
<script src="{{ buildStaticUrl('/bootstrap/bootstrap.min.js') }}"></script>
<script src="{{ buildStaticUrl('/plugins/layer/layer.js') }}"></script>
<script src="{{ buildStaticUrl('/js/common.js') }}"></script>
{%block js %}{% endblock %}
common.js获取页面的数据
buildPicUrl:function( img_key ){
var domain = $(".hidden_layout_wrap input[name=domain]").val();
var prefix_url = $(".hidden_layout_wrap input[name=prefix_url]").val();
return domain + prefix_url + img_key;
}
这样所有的配置就可以只在配置文件中改了 一次修改即可。