Django利用AJAX技术实现博文实时搜索


Posted in Python onMay 06, 2021

学习Python Web和Django开发不能只学习Python。我们有时必需借助其它技术比如AJAX实现我们想要的功能。今天我们就要利用Django 2.0 + AJAX开发一个功能性页面: 我们一边输入关键词,网页一边会给你提示所找到的博文数量。

什么是AJAX技术?它的应用场景有哪些?

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

Ajax常见应用场景包括:

  • 搜索提示: 在你输入关键词还未提交前,搜索框给你提示。
  • 用户名验证: 当你输入用户名时,页面提示你是否已注册。
  • 显示投票结果:用户投票后,不用加载页面即可显示投票结果。
  • 评论加载: 在你提交新的评论后,不用重新加载整个网页就会显示新提交的评论。

以上场景都是Django单靠自己无法实现的。注意Ajax应只用于与服务器少量数据交换,且存安全隐患,不宜广泛使用。

总体开发思路

我们创建一个叫blog的APP,并把它加入到INSTALLED_APP里去,然后在后台添加一些文章, 用于搜索(如下所示)。我们需要设计2个功能性页面: 一个展示博客文章清单,一个搜索页面。

Django利用AJAX技术实现博文实时搜索

下面我们来看下具体代码。

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

前文提到过我们需要设计2个功能性页面: 一个展示博客文章清单,一个搜索。然而在urls.py里我们却设计了3个URL。这是因为我们还要设计一个URL与AJAX进行后台数据交换。这是用户看不见的,后面我们会用到这个URL。当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

对应3个URL,我们需要在视图里编写3个处理方法,其中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利用AJAX技术实现博文实时搜索的详细内容,更多关于Django用AJAX实时搜索的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python学习资料
Feb 08 Python
Python中urllib2模块的8个使用细节分享
Jan 01 Python
浅析Python的Django框架中的Memcached
Jul 23 Python
windows下安装Python和pip终极图文教程
Mar 05 Python
python中import reload __import__的区别详解
Oct 16 Python
Python使用matplotlib实现绘制自定义图形功能示例
Jan 18 Python
在PyCharm中三步完成PyPy解释器的配置的方法
Oct 29 Python
Python多线程threading模块用法实例分析
May 22 Python
pandas DataFrame行或列的删除方法的实现示例
Aug 02 Python
python实现可下载音乐的音乐播放器
Feb 25 Python
python实现单张图像拼接与批量图片拼接
Mar 23 Python
PyQt5+Pycharm安装和配置图文教程详解
Mar 24 Python
python 如何获取页面所有a标签下href的值
May 06 #Python
Python中常见的导入方式总结
May 06 #Python
Python基础之hashlib模块详解
May 06 #Python
用Python爬虫破解滑动验证码的案例解析
python本地文件服务器实例教程
python字符串常规操作大全
python自动化之如何利用allure生成测试报告
You might like
解析如何屏蔽php中的phpinfo()函数
2013/06/06 PHP
php中current、next与reset函数用法实例
2014/11/17 PHP
php插入排序法实现数组排序实例
2015/02/16 PHP
详解Window7 下开发php扩展
2015/12/31 PHP
javaScript 数值型和字符串型之间的转换
2009/07/25 Javascript
location.href 在IE6中不跳转的解决方法与推荐使用代码
2010/07/08 Javascript
JS面向对象编程浅析
2011/08/28 Javascript
一个通过script自定义属性传递配置参数的方法
2014/09/15 Javascript
老生常谈遮罩层 滚动条的问题
2016/04/29 Javascript
详解JavaScript中基于原型prototype的继承特性
2016/05/05 Javascript
js实现弹窗暗层效果
2017/01/16 Javascript
详解用node搭建简单的静态资源管理器
2017/08/09 Javascript
js实现简易聊天对话框
2017/08/17 Javascript
AngularJS路由删除#符号解决的办法
2017/09/28 Javascript
JavaScript数组,JSON对象实现动态添加、修改、删除功能示例
2018/05/26 Javascript
Vue中mintui的field实现blur和focus事件的方法
2018/08/25 Javascript
vue中uni-app 实现小程序登录注册功能
2019/10/12 Javascript
[00:35]DOTA2上海特级锦标赛 Newbee战队宣传片
2016/03/03 DOTA
Python ORM框架SQLAlchemy学习笔记之关系映射实例
2014/06/10 Python
Python2中的raw_input() 与 input()
2015/06/12 Python
TensorFlow深度学习之卷积神经网络CNN
2018/03/09 Python
Python实现输入二叉树的先序和中序遍历,再输出后序遍历操作示例
2018/07/27 Python
python中将zip压缩包转为gz.tar的方法
2018/10/18 Python
Python OpenCV实现视频分帧
2019/06/01 Python
基于Python 中函数的 收集参数 机制
2019/12/21 Python
python实现秒杀商品的微信自动提醒功能(代码详解)
2020/04/27 Python
python Tornado框架的使用示例
2020/10/19 Python
在css3中background-clip属性与background-origin属性的用法介绍
2012/11/13 HTML / CSS
纯CSS3实现圆圈动态发光特效动画的示例代码
2021/03/08 HTML / CSS
用JAVA SOCKET编程,读服务器几个字符,再写入本地显示
2012/11/25 面试题
C++的几个面试题附答案
2016/08/03 面试题
高级护理专业大学生求职信
2013/10/24 职场文书
超市创业计划书
2014/04/24 职场文书
迎新生晚会主持词
2015/06/30 职场文书
56句经典英文座右铭
2019/08/09 职场文书
openstack云计算keystone组件工作介绍
2022/04/20 Servers