原版的mooder是没有搜索功能的,wiki.shikangsi.com的有搜索的,但是我一直觉得不太好,所以没有合并到mooder_next,现在开源这部分,如有问题还希望大家指正。
实现改功能分三步,不废话了,看下面:
1、渲染搜索起始页(首页)
其实起始页和结果页可以放一起的,我是分开了,就是一个单页,用首页改改就好了,只要样式是Amaze UI就好了,这里给出wiki的页面。
archive/searchindex.html
{% extends 'base.html' %}
{% block title %}主页{% endblock %}
{% block body %}
<div class="am-container">
<div class="am-g">
<div class="am-u-sm-centered am-u-sm-11">
<h2 style="margin:0 auto;">搜索中心</h2>
<hr>
<form class="am-form-inline am-text-center" role="form">
<div class="am-form-group am-text-center">
<input type="text" id="keyword" class="am-form-field" placeholder="请输入搜索内容">
</div>
<button type="button" id="searchBtn" class="am-btn am-btn-default">搜索</button>
</form>
</div>
</div>
</div>
{% endblock %}
我也是从Amaze UI提供的样式中直接复制来的,所以很简单。
还有几行JS
base.html
<script>
$("#searchBtn").click(function(){
var url=window.location.origin+'/search/'+$("#keyword").val();
console.log(url);
window.location.href=url;
});
</script>
这里是用GET的方式传参,传的参数在URL中,其实应该用POST,因为我改这个的时候是早期,没有考虑那么多。
2、获取条件并从数据库取数据
这部分就是后台处理,取条件和返回,后台为了保持风格统一,也是用了类来写,包括Django的一些方法。
首先是获取前端传来的关键词:
archives/url.py
path('search/', views.SearchIndexView.as_view(), name='search'),
path('search/<str:pk>', views.PostListView.as_view(), name='search-list'),
然后是进行条件筛选:
archives/views.py
# 搜索结果
class PostListView(PaginationMixin, ListView):
template_name = 'archive/search.html'
paginate_by = 15
permission_required = 'archives.change_post'
# queryset = Post.posts.all()
queryset = models.Post.posts.filter(verify='pass')
# 只要已通过的
# models.Post.posts.filter(verify='pass')
def get_queryset(self, **kwargs):
query = self.queryset
# keyword = self.request.GET.get('keyword')
keyword = self.kwargs['pk']
# print(keyword)
if keyword:
query = query.filter(title__icontains=keyword)
return query
# 搜索页面
class SearchIndexView(TemplateView):
template_name = 'archive/searchindex.html'
def get_context_data(self, **kwargs):
return super(SearchIndexView, self).get_context_data(**kwargs)
这上面的urls.py中的url取值应该是<str:keyword>,我也没改它,下面解释一下(会的可以跳过),主要是方便想快速上手进行二开的朋友明白这里的意思。
渲染页面的就跳过了,直接开始处理部分,首先是定义模板template_name、然后是分页paginate_by、接着一个权限控制permission_required(这里应该是有问题的,这个权限并不会生效,我复制的时候保留的)、queryset这里就是ORM操作了,先筛选所有已通过的数据,此时还没有对数据进行条件过滤。
重写get_queryset方法,使用self.kwargs['pk']获取传递来的关键词,用filter进行过滤,后面的语法是Django ORM中的方法,这里是一个不分大小写(icontains)的模糊查询,只要标题中存在关键词就返回,同样的还有全等于、大于、小于等条件方法。
icontains:不分大小写
contains:区分大小写
详见Django文档:
https://docs.djangoproject.com/zh-hans/4.1/ref/models/querysets/#icontains
那么后端的部分就处理完毕了。
3、渲染结果页
最后只需要将后端回传的数据渲染出来就好了。
archive/search.html
{% extends 'base.html' %}
{% load template_helper %}
{% block title %}主页{% endblock %}
{% block body %}
<div class="am-container">
<div class="am-g">
<div class="am-u-sm-centered am-u-sm-11">
<h2>搜索结果</h2>
<hr>
<table class="am-table minos-list am-text-sm am-table-bordered am-table-hover am-scrollable-horizontal">
<tr class="null am-primary">
<td width="10%" class="am-text-center am-hide-sm-down">时间</td>
<td>标题</td>
<td width="8%" class="am-text-center am-hide-sm-down">等级</td>
<td width="12%" class="am-text-center">作者</td>
</tr>
<tbody>
{% for post in post_list %}
<tr>
<td>{{ post.created_time | date:'Y-m-d' }}</td>
<td><a class="link-muted" href="{{ post.get_absolute_url }}" target="_blank">{{ post.title }}</a></td>
<td class="am-text-center am-hide-sm-down">{{ post.get_level_display | post_tag }}</td>
<td><a href="{{ post.author.get_absolute_url }}" class="link-muted" target="_blank">{{ post.author.nickname }}</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<form action="" method="post">
<input type="hidden" name="">
</form>
{% include 'archive/_pagination.html' %}
</div>
</div>
</div>
{% endblock %}
这里的样式等都是使用的统一的风格。
那么到这里就结束了,其实有了Django加持,实现这些功能还是很简单的。
若您有任何看法或意见,也请您不吝赐教,谢谢。
搜索起始页
搜索结果页
原文始发于微信公众号(墨雪飘影):开发mooder(搜索功能)【文末邀请码】
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论