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

编辑: admin 分类: python 发布时间: 2021-12-24 来源:互联网
目录
  • 什么是AJAX技术?它的应用场景有哪些?
  • 总体开发思路
  • 下面我们来看下具体代码。
    • models.py
    • urls.py
    • views.py
  • 模板blog/search.html
    • 查看效果

      学习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个功能性页面: 一个展示博客文章清单,一个搜索页面。

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

      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实时搜索的资料请关注hwidc其它相关文章!

      【本文来源:bgp服务器 欢迎转载】