快速找到想要的文章是用户比较常规的需求,所以文章搜索也是一个博客必要的功能。
实现搜索的功能,我们继续在article_list的视图中添加功能。
这里我们查询的时候一般的需求是需要输入某个字符串然后在标题和文章内容中都去匹配。
这时候我就需要使用到Django中的Q对象了。
当我们在查询的条件中需要组合条件时(例如两个条件“且”或者“或”)时。我们可以使用Q()查询对象。
我们可以使用符号&或者|将多个Q()对象组合起来传递给filter(),exclude(),get()等函数。当多个Q()对象组合起来时,Django会自动生成一个新的Q()。例如下面代码就将两个条件组合成了一个
Q(question__startswith='Who') | Q(question__startswith='What')
使用上述代码可以使用SQL语句这么理解:
WHEREquestionLIKE 'Who%' ORquestionLIKE 'What%'
接着我们来对article_list() 进行改造
- def article_list(request):
- # 根据GET请求中查询条件
- # 返回不同排序的对象数组
- search = request.GET.get('search')
- order = request.GET.get('order')
- # 用户搜索逻辑
- if search:
- if order == 'total_views':
- # 用 Q对象 进行联合搜索
- article_list = Article.objects.filter(
- Q(title__icontains=search) |
- Q(body__icontains=search)
- ).order_by('-total_views')
- else:
- article_list = Article.objects.filter(
- Q(title__icontains=search) |
- Q(body__icontains=search)
- )
- else:
- # 将 search 参数重置为空
- search = ''
- if order == 'total_views':
- article_list = Article.objects.all().order_by('-total_views')
- else:
- article_list = Article.objects.all()
-
- paginator = Paginator(article_list, 2)
- page = request.GET.get('page')
- articles = paginator.get_page(page)
-
- # 修改此行
- context = {'articles': articles, 'order': order, 'search': search }
-
- return render(request, 'article/list.html', context)
主要修订如下:
接着改造list模板,要修改的代码比较多,实际上功能上没多大改变,直接贴list.html 的完整代码如下:
templates/article/list.html
- {% extends "base.html" %}
- {% load static %}
-
- {% block title %}
- 首页
- {% endblock title %}
-
- {% block content %}
- {##}
-
- class="container">
-
-
class="breadcrumb">
-
- class="breadcrumb-item">
- 最新
-
-
-
- class="breadcrumb-item">
- 最热
-
-
-
-
-
- class="row">
- class="col-auto mr-auto">
-
- {# #}
- <input type="text"
- class="form-control mb-2 mr-sm-2"
- name="search"
- placeholder="搜索文章..."
- required
- >
-
-
-
-
- {% if search %}
- {% if articles %}
-
"color: red">"{{ search }}"的搜索结果如下:
-
- {% else %}
-
暂无"color: red">"{{ search }}"有关的文章。
-
- {% endif %}
- {% endif %}
- {% for article in articles %}
- class="row mt-2">
-
- class="col-sm-12">
-
- class="card h-100">
-
-
- class="card-body">
-
class="card-title">{{ article.title }}
-
-
class="card-text">{{ article.body|slice:'100' }}...
-
- class="col align-self-end" style="color: gray;">
- class="bi bi-eye">
- {{ article.total_views }}
-
-
-
-
-
-
- {% endfor %}
-
- class="pagination row">
- class="m-auto">
- class="step-links">
-
- {% if articles.has_previous %}
- « 1
-
- ...
- class="btn btn-secondary"
- >
- {{ articles.previous_page_number }}
-
- {% endif %}
-
- class="current btn btn-danger btn-lg">
- {{ articles.number }}
-
-
- {% if articles.has_next %}
- class="btn btn-secondary">{{ articles.next_page_number }}
- ...
- class="btn btn-success">{{ articles.paginator.num_pages }} »
- {% endif %}
-
-
- {##}
-
- {% endblock content %}
重点改动如下:
完成后测试效果如下:

截止到本篇,我们已经完成了博客文章,评论和用户管理的核心功能,同时也实现了简单的排序和搜索等必要的小功能模块。
本系列博文的核心模块将告一段落,下篇我们来完成最终的挑战:部署上线。