今天我滴戶外網(wǎng)站開發(fā)進(jìn)度走到了多條件搜索活動(dòng)的界面寂曹,不難但是涉及的細(xì)節(jié)很多馍资,所以簡(jiǎn)單記錄下
先上實(shí)現(xiàn)截圖:
搜索功能實(shí)現(xiàn)效果圖
具體實(shí)現(xiàn)一步步走起~
創(chuàng)建Form以及Form的布局顯示
這個(gè)搜索框也可以直接拋棄Form....
表單類創(chuàng)建了需要的field并賦值
class ActivitySearchForm(Form):
keyword = StringField('搜索關(guān)鍵字')
outdoor = RadioField('活動(dòng)類型')
days = RadioField('出行天數(shù)')
sort = RadioField('排序方式')
submit = SubmitField('搜索活動(dòng)')
def __init__(self, *args, **kwargs):
super(ActivitySearchForm, self).__init__(*args, **kwargs)
#為單選鈕賦默認(rèn)值
self.outdoor.choices = [(item.id, item.name) for item in OutdoorType.show_list()]
days_source = [(1, '1天'), (3, '2-3天'), (7, '4-7天'), (15, '8-15天'), (16, '16天以上')]
self.days.choices = days_source
sort_source = [(0, '最新發(fā)布'), (1, '最多訪問(wèn)'), (2, '價(jià)格由低到高'), (3, '價(jià)格由高到低')]
self.sort.choices = sort_source
界面選擇表格布局抹恳,代碼:
<form action="" method="post" class="form-horizontal" role="form">
{{ form.hidden_tag() }}
<table class="table vertical-center">
<tbody>
<tr class="active">
<td class="highlight">搜索關(guān)鍵字</td>
<td><div class="col-sm-6">
{{ form.keyword(class_='form-control') }}
</div>
<div class="col-sm-2">
{{ form.submit(class_='btn btn-warning') }}
</div>
</td>
</tr>
<tr class="warning">
<td class="highlight">活動(dòng)類型</td>
<td>{{ form.outdoor(class_='radio-list-inline') }}</td>
</tr>
<tr class="active">
<td class="highlight">出行天數(shù)</td>
<td>{{ form.days(class_='radio-list-inline') }}</td>
</tr>
<tr class="warning">
<td class="highlight">排序類型</td>
<td>{{ form.sort(class_='radio-list-inline') }}</td>
</tr>
</tbody>
</table>
</form>
在活動(dòng)類'Activity`中添加一個(gè)根據(jù)篩選項(xiàng)取得活動(dòng)的方法
這里就是不停迭代filter_by
和order_by
這里有一點(diǎn)需要注意棋电,搜索框里面的幾個(gè)單選鈕摇锋,如果沒(méi)有選擇都返回'None',是None這個(gè)字符串祈争,而部署None類型斤程,所以判斷的時(shí)候用的都是!= 'None'
這個(gè)還值得注意的是用空白分隔的關(guān)鍵字做搜索的實(shí)現(xiàn)
最后把query構(gòu)建好了,用paginate分頁(yè)取回活動(dòng)
@staticmethod
def get_activities_search(keyword, outdoor, days, sort, page=1):
activities = Activity.query
if outdoor != 'None': #戶外類型
t = OutdoorType.query.get(int(outdoor))
activities = t.activities
if keyword:#允許多個(gè)空格分隔的搜索關(guān)鍵字
keywords = keyword.split()
for k in keywords:
activities = activities.filter(Activity.name.like('%'+k+'%'))
if days != 'None': #出行天數(shù)
if days == '1':
activities = activities.filter(Activity.days == 1)
elif days == '3':
activities = activities.filter(or_(Activity.days == 2, Activity.days == 3))
elif days == '7':
activities = activities.filter(and_(Activity.days > 3, Activity.days < 8))
elif days == '15':
activities = activities.filter(and_(Activity.days > 7, Activity.days < 16))
else:
activities = activities.filter(Activity.days > 15)
if sort != 'None':#排序
if sort == '1':
activities = activities.order_by(Activity.view_count.desc())
elif sort == '2':
activities = activities.order_by(Activity.price.asc())
elif sort == '3':
activities = activities.order_by(Activity.price.desc())
else:
activities = activities.order_by(Activity.timestamp.desc())
return activities.paginate(page, current_app.config['PAGECOUNT_ACTIVITY'], error_out=False)
在View里面添加處理邏輯
在分頁(yè)瀏覽中使用session
保存搜索條件菩混,每次POST修改搜索條件的時(shí)候忿墅,記得把page設(shè)成1
@team.route('/activites/search', methods=['GET', 'POST'])
def activities_search():
form = ActivitySearchForm()
page = request.args.get('page', 1, type=int)
if request.method == 'POST':
#每次POST,添加查詢字符串沮峡,取回第一頁(yè)
session['activity-keyword'] = form.keyword.data
session['activity-outdoor'] = form.outdoor.data
session['activity-days'] = form.days.data
session['activity-sort'] = form.sort.data
page = 1
pagination = Activity.get_activities_search(
session.get('activity-keyword', ""),
session.get('activity-outdoor', 'None'),
session.get('activity-days', 'None'),
session.get('activity-sort', 'None'),
page
)
activities = pagination.items
return render_template('activities_search.html',
form=form,
activities = activities,
pagination = pagination)
這里需要特別注意的是疚脐,因?yàn)槭褂昧?code>session,所以在從別的頁(yè)面直接跳轉(zhuǎn)到搜索頁(yè)時(shí)邢疙,顯示的是session搜索條件下的活動(dòng)亮曹,所以在跳轉(zhuǎn)前要將session清空