Django结合Ajax的三个demo

利用Ajax技术实现页面的局部刷新,降低服务器的压力。
Ajax是爬虫、前端、后台不分家的地方。之前遇到过蛮多的,所以自己实现一下。做了一段时间的东西了,此处做一下汇总。

此处两个demo:

  • xhr翻页
  • 实现购物车功能(Ajax配合session)
  • 搜索提示

1.xhr翻页

动态从后台数据库读取一部分数据,并作为json返回,前端用js遍历出来

# urls.py
from django.urls import path
from ajax_data.views import *

urlpatterns = [
    path('add/', insert_into_databases),
    path('index/', index),
    path('get_json/', send_json),
]

# views.py
from django.shortcuts import render, HttpResponse
from .models import AjaxData
import random
from random import randint
import string
import json
# Create your views here.

# 生成随机数据并插入到数据库
def insert_into_databases(request):
    for i in range(20):
        AjaxData.objects.create(
            title='数学_' + ''.join([random.choice(string.ascii_letters) for i in range(5)]),
            price=randint(10, 30),
            comments=randint(100, 666),
        )
    return HttpResponse('Successfully insert')


def index(request):
    return render(request, 'dynamic_web_page.html')


def send_json(request):
    offset = request.GET.get('offset')
    print(type(offset), offset)
    x = int(offset)
    books = AjaxData.objects.all()[x: x + 5]
    print(books)
    # 构造字典,下面转换为json
    json_data = {'book_list': []}
    for book in books:
        _dict = {'title': book.title, 'price': book.price, 'comments': book.comments}
        json_data['book_list'].append(_dict)
    # 将python对象转换为json对象返回给js进行处理
    return HttpResponse(json.dumps(json_data), content_type='application/json')


# dynamic_web_page.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
    <script src="http://apps.bdimg.com/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<header>商品列表</header>
<div>&nbsp;</div>
<div class="get-json"></div>
<form action="/get_json/" method="get">
    <ul class="pagination">
        <li class="page-item active"><a class="page-link" href="#">1</a></li>
        <li class="page-item"><a class="page-link" href="#">2</a></li>
        <li class="page-item"><a class="page-link" href="#">3</a></li>
        {#  如果没写form表单,直接href="/get_json/"的话,是不会触发js事件的      #}
        {#  要触发js事件:1. 添加form表单  2. 给href属性指定一个实名函数,在实名函数里面写方法      #}
        <li class="page-item"><a class="page-link" href="#">4</a></li>
{#        <li class="page-item"><a class="page-link" href="javaScript:send()">4</a></li>#}
    </ul>
</form>
<footer>页脚</footer>

<script>

    function send(){
        $.get("/get_json/", {'offset': '4'}, function (json) {
            console.log(json);
            for (var i = 0; i < json['book_list'].length; i++) {
                var title = "<p>" + json['book_list'][i]['title'];
                var price = json['book_list'][i]['price'];
                var comments = json['book_list'][i]['comments'] + "</p>";
                var divElement = "<div>" + title + " &nbsp;&nbsp;&nbsp; ¥" + price + "&nbsp;&nbsp;&nbsp;   评论数:" +comments + "</div>";
                console.log(divElement);
                $('div.get-json').append(divElement);
            }
        });
    }

    $(document).ready(function () {
    	//首页的数据
        $.get("/get_json/", {'offset': '0'}, function (json) {
            console.log(json);
            for (var i = 0; i < json['book_list'].length; i++) {
                    var title = "<p>" + json['book_list'][i]['title'];
                    var price = json['book_list'][i]['price'];
                    var comments = json['book_list'][i]['comments'] + "</p>";
                    var divElement = "<div>" + title + " &nbsp;&nbsp;&nbsp; ¥" + price + "&nbsp;&nbsp;&nbsp;   评论数:" +comments + "</div>";
                    console.log(divElement);
                    $('div.get-json').append(divElement);
            }
        });
        //根据按钮的值进行Ajax请求并遍历json
        var liList = $('li.page-item');
        for (var i = 0; i < liList.length; i++) {
            $(liList[i]).click(function () {
                $('div.get-json').empty();
                var innerText = $(this).children('a').text();
                console.log(innerText);
                var offset = (parseInt(innerText) - 1) * 5;
                console.log(offset);
                $.get("/get_json/", {'offset': offset}, function (json) {
                    console.log(json);
                    for (var i = 0; i < json['book_list'].length; i++) {
                        var title = "<p>" + json['book_list'][i]['title'];
                        var price = json['book_list'][i]['price'];
                        var comments = json['book_list'][i]['comments'] + "</p>";
                        var divElement = "<div>" + title + " &nbsp;&nbsp;&nbsp; ¥" + price + "&nbsp;&nbsp;&nbsp;   评论数:" +comments + "</div>";
                        console.log(divElement);
                        $('div.get-json').append(divElement);
                    };
                })
            });
        }
    });
</script>
</body>
</html>

2.实现购物车功能

两个页面,第一个可以自由的选择商品。第二个页面可以自由移除商品,并使用js进行页面元素的删除。为了只跑一次SQL,提升性能,此处使用session来保存用户所选择的商品。

# urls.py
from django.contrib import admin
from django.urls import path, re_path
from .views import *

urlpatterns = [
    path('shopping/', shopping, name='shopping'),
    path('selected_show/', selected_show, name="select_show"),
    path('parse_shopping/', parse_shopping, name='parse_shopping'),
    re_path('del_session/product_id=(\d+)/', delete_session, name='del_session'),
    path('del_session_by_ajax/', del_session_by_ajax)
]

# views.py
def shopping(request):
    return render(request, 'shopping.html')



def parse_shopping(request):
    # 这个方法一次只能添加一个商品
    print(request.session.items())
    product = request.POST.get('product', '')
    price = request.POST.get('price', '')
    product_id = request.POST.get('id', '')
    print(product, price, product_id)
    # 用 product_id 标识 该商品所对应的session
    key_name = 'product_' + product_id
    if product_id:
        # product_list = request.session.get('product', [])
        # if not product in product_list:
        #     product_list.append({'id': product_id, 'product': product, 'price': price})
        request.session[key_name] = {'id': product_id, 'product': product, 'price': price}
        return HttpResponse(f'商品:{product}  价格:{price}元  id:{product_id}')
    else:
        return redirect('/')


def selected_show(request):
    session_keys = request.session.items()
    print(session_keys)
    return render(request, 'del_product.html', locals())

"""
def delect_session(request):
    price_data = request.GET.get('id_price')
    print(price_data)
    memorize_product_name = 'None'
    # for key, value in request.session.items():
    #     print(key, value)
    for key, value in request.session.items():
        if value.endswith(price_data):
            memorize_product_name = key
            del request.session[key]
    return HttpResponse(memorize_product_name + '删除成功')
"""
def delete_session(request, product_id):
    print(product_id)
    for key, value in request.session.items():
        if value.get('id') == product_id:
            del request.session[key]
            break # 会出现错误 - > dictionary changed size during iteration , 加一个break就好了
    session_keys = request.session.items()
    return render(request, 'show_cart_new.html', locals())
    # return redirect('select_show', locals())


def del_session_by_ajax(request):
    product_id = request.POST.get('product_id', '')
    for key, value in request.session.items():
        if value.get('id') == product_id:
            del request.session[key]
            break
    return HttpResponse('id为{}的商品已被移除购物车'.format(product_id))

前端页面

# shopping.html 购物页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>shopping</title>
    <style>
        .fix-here {
            {#margin-left: 300px;#}
        }
    </style>
</head>
<body>
    {#{% url 'parse_shopping' %}#}
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <ul id="first" style="list-style: none;">
     <li><p class="product">A商品</p><p class="price">30</p><a href="#" id="1">点击抢购</a></li>
     <li><p class="product">B商品</p><p class="price">40</p><a href="#" id="2">点击抢购</a></li>
     <li><p class="product">C商品</p><p class="price">50</p><a href="#" id="3">点击抢购</a></li>
     <li><p class="product">D商品</p><p class="price">60</p><a href="#" id="4">点击抢购</a></li>
    </ul>
    <a href="{% url 'select_show' %}">进入购物车</a>
    <br>
    <div>
        已选购商品数
        <span id="dynamic-number">0</span>
    </div>
    <script>
        var num = 0;
        var myUl = document.getElementById('first');
        var liList = myUl.getElementsByTagName('li');
        var len = liList.length;
        for (var i = 0; i < len; i++) {
            liList[i].onclick = function (ele) {
                var element = ele.target;
                console.log(element);
                num += 1;
                alert('添加商品成功');
                $('dynamic-number').innerText = num;

                var productPrice = $(element).prev().text();
                var productName = $(element).prev().prev().text();
                var productId = $(element).attr('id');

                $.ajax({
                    url:'{% url "parse_shopping" %}',
                    type:'POST',
                    data: {'product': productName, 'price': productPrice, 'id': productId},
                    success: function (data) {
                        alert(data);
                    }
                });

            };
        }

    </script>
</body>
</html>


# del_product.html 购物车

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>show cart</title>
</head>
<body>
    <ul>
        {% for session_key, value_dict in session_keys %}
            <li>{{ value_dict.product }}  {{ value_dict.price }}元</li>
            <button class="del-it" id="{{ value_dict.id }}">移除商品</button>
        {% endfor %}
    </ul>
    <div>123</div>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>
        /*
        var btnList = document.getElementsByClassName('del-it');
        for (var i = 0; i < btnList.length; i++) {
            var element = $(btnList[i]);
            element.onclick = function () {
               var inner_text = this.prev().text();
                var pattern = /.*?(\d{2})元/g;
                var result = inner_text.match(pattern);

                this.remove();
                this.prev().remove();
            };

        }
        */
        var btnList = document.getElementsByClassName('del-it')
        for(var i = 0; i < btnList.length; i++) {
            // 遍历给元素附上事件
            $(btnList[i]).click(function() {
                var productId = $(this).attr("id");
                $(this).prev().remove();
                $(this).remove();
                $.ajax({
                    url: "/del_session_by_ajax/",
                    data: {"product_id": productId},
                    type: "POST",
                    success: function (data) {
                        // Ajax请求成功以后进行元素的删除
                        alert(data);
                    }
                })
            });
        }
    </script>
</body>
</html>

3.实现搜索提示

设置事件监听键盘的起落,动态发送已经键入的关键词到后台,后台进行数据库查询并返回json,然后用js遍历json

urls.py
from django.urls import path
from Ajax_search.views import search_name
from .views import index

urlpatterns = [
    path('Fsearch/', search_name),
    path('', index),
]

# views.py
from django.shortcuts import render, HttpResponse
from Ajax_search.models import AjaxSearch
import json
# Create your views here.

def search_name(request):
    keyword = request.GET.get('keyword', '')
    name_list = AjaxSearch.objects.filter(have_been_searched__contains=keyword)
    # 将QuerySet对象的列表list一下,这样才可以处理里面的对象了
    json_source = list(map(lambda item: item.have_been_searched, name_list))
    return HttpResponse(json.dumps(json_source), content_type='application/json')

html

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8"/>
<body>
    <div style="margin-top: 300px;margin-left: 520px;">
        <form action="/Fsearch/" method="get" style="margin: auto 0;">
            请输入要查询的关键字:<br/>
            <input type="text" id="search-text" name="keyword"><button type="button" id='search-button'>搜索</button>
            <p><span id='search-result'></span></p>
        </form>
    </div>
<script src="http://apps.bdimg.com/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
    $(document).ready(function(){
        $("#search-text").keyup(function(){
            var keyword = $("#search-text").val();
            //当表单的值是一个空字符串,并且是最后删除完东西的时候
            if (keyword == '') {
                console.log('The form value is empty.');
                return;
            }
            $.get("/Fsearch/",{'keyword': keyword}, function(data){
                for (var i = 0;i < data.length; i++) {
                    $('#search-result').append(data[i]+'<br/>')
                }
            });
        });
        $('#search-text').keydown(function(){
            $('#search-result').empty();
        });

        $('#search-text').blur(function(){
            $('#search-result').empty();
        });

    });
</script>
</body>
</html>

事实上,知识之间都是有交汇的地方的。学得精才是正道。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值