Django结合AJAX实现博文实时搜索功能
本文介绍如何在Django 2.0中利用AJAX技术实现博文实时搜索功能。通过前后端分离的设计思路,前端在用户输入关键词时异步发送请求,后端仅返回匹配文章的数量而非完整列表,从而提升用户体验并减少服务器负载。文章详细讲解了URL配置、视图处理逻辑以及前端JavaScript的交互实现。
在进行Python Web及Django开发时,单纯掌握Python语言往往不足以应对所有需求,有时需要结合其他前端技术来实现特定功能。本文将演示如何使用Django 2.0配合AJAX技术,构建一个具备实时反馈功能的页面:当用户在输入框键入关键词时,页面会即时显示当前匹配到的博文数量。
了解AJAX技术及其应用
AJAX全称为“Asynchronous Javascript And XML”(异步JavaScript和XML),是一种用于创建交互式网页应用的开发技术。其核心机制是在后台与服务器进行少量数据交换,从而允许网页在不重新加载整个页面的情况下,对页面的局部内容进行更新。
AJAX的典型应用场景包括:
- 搜索建议:在用户输入关键词且尚未提交表单前,动态提供搜索提示。
- 用户名校验:在用户输入用户名时,实时提示该用户名是否已被注册。
- 投票结果展示:用户完成投票后,无需刷新页面即可直接显示统计结果。
- 评论加载:用户提交新评论后,页面无需重载即可显示最新评论内容。
上述场景均无法仅靠Django原生功能单独实现。需要注意的是,AJAX适用于与服务器进行少量数据交换的场景,且由于存在潜在的安全隐患,不应被滥用或广泛部署于所有交互中。
整体开发思路
首先创建一个名为blog的应用,并将其注册到INSTALLED_APPS中。在后台预置若干文章数据以供搜索测试。我们需要设计两个主要功能页面:一个是展示博客文章列表的页面,另一个是专门用于搜索的页面。

具体代码实现
models.py
本案例使用的Article模型定义如下:
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from django.utils.timezone import now
class Article(models.Model):
STATUS_CHOICES = (
('d', '草稿'),
('p', '发表'),
)
title = models.CharField('标题', max_length=200, unique=True)
slug = models.SlugField('slug', max_length=60)
body = models.TextField('正文')
pub_date = models.DateTimeField('发布时间', default=now, null=True)
create_date = models.DateTimeField('创建时间', auto_now_add=True)
mod_date = models.DateTimeField('修改时间', auto_now=True)
status = models.CharField('文章状态', max_length=1, choices=STATUS_CHOICES, default='p')
views = models.PositiveIntegerField('浏览量', default=0)
author = models.ForeignKey(User, verbose_name='作者', on_delete=models.CASCADE)
def __str__(self):
return self.title
class Meta:
ordering = ['-pub_date']
verbose_name = "文章"
urls.py
前文提到需要两个功能性页面(文章列表和搜索页),但在urls.py中我们配置了三个URL。这是因为还需要一个专门用于AJAX后台数据交换的URL。该URL对用户不可见,后续将用于处理AJAX请求。当AJAX向/blog/ajax/search/发送请求时,Django将调用ajax_search视图函数进行处理。
from django.urls import path, re_path
from . import views
# namespace
app_name = 'blog'
urlpatterns = [
# 搜索文章
re_path(r'^search/$', views.article_search, name='article_search'),
# 用于与ajax交互
re_path(r'^ajax/search/$', views.ajax_search, name='ajax_search'),
# 展示所有文章
path('', views.ArticleListView.as_view(), name='article_list'),
]
views.py
对应三个URL,我们需要在视图中编写三个处理函数。其中,ajax_search负责向搜索页面返回JSON格式的数据(即查询到的文章数量);article_search负责返回具体的搜索结果列表。之所以不通过ajax_search返回完整搜索结果,是因为查询数据集可能非常大,而AJAX的设计初衷仅适用于与服务器的少量数据交换。
from django.views.generic import ListView
from .models import Article
from django.shortcuts import render
from .forms import SearchForm
from django.http import JsonResponse
# Create your views here.
class ArticleListView(ListView):
queryset = Article.objects.filter(status='p').order_by('-pub_date')
paginate_by = 6
def article_search(request):
if request.method == 'GET':
form = SearchForm(request.GET)
if form.is_valid():
keyword = form.cleaned_data.get("keyword")
if keyword:
article_list = Article.objects.filter(title__icontains=keyword)
return render(request, 'blog/search.html', {'form': form, 'article_list': article_list})
else:
form = SearchForm()
return render(request, 'blog/search.html', {'form': form, 'article_list': False, })
def ajax_search(request):
if request.method == 'GET':
keyword = request.GET.get('keyword', None)
if keyword:
count = Article.objects.filter(title__icontains=keyword).count()
data = {'count': count, }
return JsonResponse(data)
下面重点分析ajax_search的工作机制:
- 当搜索页面的AJAX通过GET方式发送请求时,服务器端获取AJAX传递过来的keyword参数。
- 若keyword不为空,服务器执行查询,统计标题中包含该keyword的文章数量。
- 服务器将结果封装为字典{‘count': count },转换为JSON数据格式后返回给前端AJAX所在的页面。
模板文件blog/search.html
我们的模板文件blog/search.html代码如下:
{% block content %}
<h3>Django Ajax实时搜索文章</h3>
<form method="get" action="">{% csrf_token %}
{{ form }}
<input type="submit" value="Search" />
</form>
{% endblock %}
<div id="result"></div>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script>
$("#id_keyword").bind('input propertychange', function() {
var keyword = $(this).val();
$.ajax({
url: '/blog/ajax/search/',
data: {
'keyword': keyword
},
type: 'GET',
dataType: 'json',
success: function (data) {
$("#result").html("<p>正在实时查询...共" + data.count + "条记录</p>")
},
});
});
</script>
{% if article_list %}
<p>共找到 {{ article_list | length }} 条记录。</p>
<ul>
{% for article in article_list %}
<li><a href="{% url 'blog:article_detail' article.id %}" rel="external nofollow" > {{ article.title }}</a> {{ article.pub_date | date:"Y-m-j" }}</li>
{% endfor %}
</ul>
{% endif %}
接下来重点解析AJAX在前端的工作流程。
- 当搜索框#id_keyword发生属性变化(如用户输入)时,AJAX实时获取#id_keyword的值,并通过GET方法将数据发送至url('/blog/ajax/search')。
- Django视图中的ajax_search方法接收并处理AJAX发来的请求,随后返回JSON数据。
- 若服务器响应成功并返回有效的JSON数据,前端将把数据显示在id为result的DIV元素中。
效果展示
下图展示了实时显示搜索结果数量的效果。随着关键词字符的增加,匹配到的结果数量逐渐减少。

以上即为Django利用AJAX技术实现博文实时搜索的完整流程,更多关于Django实时搜索的资料,敬请关注本站后续文章。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













