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 11 Python
python在linux系统下获取系统内存使用情况的方法
May 11 Python
JSONLINT:python的json数据验证库实例解析
Nov 28 Python
Tensorflow实现卷积神经网络用于人脸关键点识别
Mar 05 Python
python 遍历列表提取下标和值的实例
Dec 25 Python
学习Django知识点分享
Sep 11 Python
python 实现return返回多个值
Nov 19 Python
python 消除 futureWarning问题的解决
Dec 25 Python
python实现用类读取文件数据并计算矩形面积
Jan 18 Python
Python Django form 组件动态从数据库取choices数据实例
May 19 Python
关于keras中keras.layers.merge的用法说明
May 23 Python
基于Python爬取51cto博客页面信息过程解析
Aug 25 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 UTF8编码内的繁简转换类
2009/07/20 PHP
总结PHP内存释放以及垃圾回收
2018/03/29 PHP
PHP+Redis链表解决高并发下商品超卖问题(实现原理及步骤)
2020/08/03 PHP
jQuery学习笔记之jQuery选择器的使用
2010/12/22 Javascript
jQuery创建平滑的页面滚动(顶部或底部)
2013/02/26 Javascript
js 获取(接收)地址栏参数值的方法
2013/04/01 Javascript
js怎么终止程序return不行换jfslk
2013/05/30 Javascript
jquery无刷新验证邮箱地址实现实例
2014/02/19 Javascript
JQuery以JSON方式提交数据到服务端示例代码
2014/05/05 Javascript
Javascript前端UI框架Kit使用指南之Kitjs简介
2014/11/28 Javascript
node实现定时发送邮件的示例代码
2017/08/26 Javascript
js字符限制(字符截取) 一个中文汉字算两个字符
2017/09/12 Javascript
一步步教你利用Canvas对图片进行处理
2017/09/19 Javascript
JavaScript实现的贝塞尔曲线算法简单示例
2018/01/30 Javascript
使用 vue.js 构建大型单页应用
2018/02/10 Javascript
微信小程序冒泡事件及其阻止方法实例分析
2018/12/06 Javascript
[32:39]完美世界DOTA2联赛循环赛 Forest vs Inki BO2第一场 11.04
2020/11/04 DOTA
使用Python的Flask框架表单插件Flask-WTF实现Web登录验证
2016/07/12 Python
如何利用python查找电脑文件
2018/04/27 Python
Python基于聚类算法实现密度聚类(DBSCAN)计算【测试可用】
2018/12/26 Python
CSS3的calc()做响应模式布局的实现方法
2017/09/06 HTML / CSS
Kipling凯浦林美国官网:世界著名时尚休闲包袋品牌
2016/08/24 全球购物
纽约JewelryAffairs珠宝店:精细金银时尚首饰
2017/02/05 全球购物
GUESS德国官网:美国牛仔服装品牌
2017/02/14 全球购物
JAVA和C++的区别
2013/10/06 面试题
广告学专业毕业生自荐信
2013/09/24 职场文书
自荐信结尾
2013/10/27 职场文书
网络专业学生个人的自我评价
2013/12/16 职场文书
校本教研工作方案
2014/01/14 职场文书
预备党员群众路线教育实践活动思想汇报2014
2014/10/25 职场文书
公务员年度考核个人总结
2015/02/12 职场文书
搞笑老公保证书
2015/02/26 职场文书
工厂采购员岗位职责
2015/04/07 职场文书
一篇文章带你深入了解Mysql触发器
2021/08/02 MySQL
postman中form-data、x-www-form-urlencoded、raw、binary的区别介绍
2022/01/18 HTML / CSS
Springboot集成kafka高级应用实战分享
2022/08/14 Java/Android