Django之Ajax

一、Ajax简介

 

异步提交,局部刷新

AJAX 不是新的编程语言,而是一种使用现有标准的新方法

AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;

异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

二、Ajax基本语法

1.index.html

<input type="text" id="d1"> +
<input type="text" id="d2"> =
<input type="text" id="d3">
<p>
    <button id="btn">点我</button>
</p>

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
    // 先给按钮绑定一个点击事件
    $('#btn').click(function () {
        // 朝后端发送ajax请求
        $.ajax({
            // 1.指定朝哪个后端发送ajax请求
            url: '', // 不写就是朝当前地址提交
            // 2.请求方式
            type: 'post',    // 不指定默认就是get 都是小写
            // 3.数据
            data: {'i1': $('#d1').val(), 'i2': $('#d2').val()},
            // 4.回调函数:当后端给你返回结果的时候会自动触发 args接收后端返回结果
            success: function (args) {
                {#alert(args)#}
                $('#d3').val(args)
            }
        })
    })
</script>

2.views.py

from django.shortcuts import render, HttpResponse

def ab_ajax(request):
    if request.method == "POST":
        # print(request.POST)
        i1 = request.POST.get('i1')
        i2 = request.POST.get('i2')
        # 先转成整形再加
        i3 = int(i1) + int(i2)
        print(i3)
        return HttpResponse(i3)
    return render(request, 'index.html')

3.urls.py

from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('ab_ajax/', views.ab_ajax),
    # ajax发送json格式数据
    path('ab_json/', views.ab_json),
    # ajax发送文件
    path('ab_file/', views.ab_file),
    # 序列化组件相关
    path('ab_ser/', views.ab_ser),
    # 批量插入数据
    path('ab_pl/', views.ab_pl),
]

二、Ajax发送数据

1.Ajax发送json格式数据

1.1.ab_json.html

<button class="btn btn-danger" id="d1">点我</button>

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
    $('#d1').click(function () {
        $.ajax({
            url: '',
            type: 'post',
            data: JSON.stringify({'username': 'qiansuiyou', 'age': 100}),   // {"username":"qiansuiyou","age":100}
            contentType: 'application/json', // 指定编码格式
            success: function (args) {
                
            }
        })
    })
</script>

1.2.views.py

def ab_json(request):
    json_bytes = request.body
    print(json_bytes, type(json_bytes))    # b'{"username":"qiansuiyou","age":100}' <class 'bytes'>
    return render(request, 'ab_json.html')

2.Ajax发送文件数据

2.1.ab_file.html

<p>username:<input type="text" id="d1"></p>
<p>password:<input type="text" id="d2"></p>
<p><input type="file" id="d3"></p>
<button id="d4">点我</button>

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
    // 点击按钮朝后端发送普通键值对和文件数据
    $('#d4').on('click', function () {
        // 1.需要先利用FormData内置对象
        let formDateObj = new FormData();
        // 2.先添加普通的键值对
        formDateObj.append('username', $('#d1').val());
        formDateObj.append('password', $('#d2').val());
        // 3.添加文件对象
        formDateObj.append('myfile', $('#d3')[0].files[0]);
        // 4.将对象基于Ajax发送给后端
        $.ajax({
            url: '',
            type: 'post',
            data: formDateObj,   // 直接将对象放入data后面即可
            //Ajax发送文件必须要指定的两个参数
            contentType: false,  // 不需要使用任何编码 django后端能够自动识别formdata对象
            processData: false, // 告诉你的浏览器不要对你的数据进行任何处理
            success: function () {

            }
        })
    })
</script>

2.2views.py

def ab_file(request):
    if request.method == 'POST':
        print(request.POST)
        print(request.FILES)
    return render(request, 'ab_file.html')

三、django自带的序列号组件

1.models.py

class User(models.Model):
    username = models.CharField(max_length=32, verbose_name='姓名')
    age = models.IntegerField(verbose_name='年龄')
    gender_choices = (
        (1, 'male'),
        (2, 'female'),
        (3, 'others')
    )
    gender = models.IntegerField(choices=gender_choices, verbose_name='性别')

class Book(models.Model):
    title = models.CharField(max_length=32)

  

 2.views.py

from django.shortcuts import render, HttpResponse
from app01 import models
from django.http import JsonResponse
from django.core import serializers

def ab_ser(request):
    user_queryset = models.User.objects.all()
    # user_list = []
    # for user_obj in user_queryset:
    #     tmp = {
    #         'pk': user_obj.pk,
    #         'username': user_obj.username,
    #         'age': user_obj.age,
    #         'gender': user_obj.get_gender_display()
    #     }
    #     user_list.append(tmp)
    # return JsonResponse(user_list, safe=False)
    # 序列化模块
    res = serializers.serialize('json', user_queryset)
    return HttpResponse(res)

四、批量插入数据

1.ab_pl.html

{% for book_obj in book_queryset %}
    <p>{{ book_obj.title }}</p>
{% endfor %}

2.views.py

def ab_pl(request):
    # 先给Book插入1000条数据
    # for i in range(1000):
    #     models.Book.objects.create(title=f'第{i}本书')
    # 在将所有的数据查询并展示到前端页面
    # book_queryset = models.Book.objects.all()
    # 批量插入
    book_list = []
    for i in range(1000):
        book_obj = models.Book(title=f'第{i}本书')
        book_list.append(book_obj)
    models.Book.objects.bulk_create(book_list)
    book_queryset = models.Book.objects.all()
    """当你想要批量插入数据的时候使用orm给你提供的bulk_create能够大大的减少操作时间"""
    return render(request, 'ab_pl.html', locals())

五、自定义分页器

当需要使用到非django内置的第三方功能或者组件代码的时候

一般情况下会创建一个名为utils文件夹,在该文件夹内对模块进行功能性划分

自定义分页器是基于bootstrap3样式来的,所有需要提前导入bootstrap3

1.utils/mypage.py

class Pagination(object):
    def __init__(self, current_page, all_count, per_page_num=10, pager_count=11):
        """
        封装分页相关数据
        :param current_page: 当前页
        :param all_count:    数据库中的数据总条数
        :param per_page_num: 每页显示的数据条数
        :param pager_count:  最多显示的页码个数
        """
        try:
            current_page = int(current_page)
        except Exception as e:
            current_page = 1

        if current_page < 1:
            current_page = 1

        self.current_page = current_page

        self.all_count = all_count
        self.per_page_num = per_page_num

        # 总页码
        all_pager, tmp = divmod(all_count, per_page_num)
        if tmp:
            all_pager += 1
        self.all_pager = all_pager

        self.pager_count = pager_count
        self.pager_count_half = int((pager_count - 1) / 2)

    @property
    def start(self):
        return (self.current_page - 1) * self.per_page_num

    @property
    def end(self):
        return self.current_page * self.per_page_num

    def page_html(self):
        # 如果总页码 < 11个:
        if self.all_pager <= self.pager_count:
            pager_start = 1
            pager_end = self.all_pager + 1
        # 总页码  > 11
        else:
            # 当前页如果<=页面上最多显示11/2个页码
            if self.current_page <= self.pager_count_half:
                pager_start = 1
                pager_end = self.pager_count + 1

            # 当前页大于5
            else:
                # 页码翻到最后
                if (self.current_page + self.pager_count_half) > self.all_pager:
                    pager_end = self.all_pager + 1
                    pager_start = self.all_pager - self.pager_count + 1
                else:
                    pager_start = self.current_page - self.pager_count_half
                    pager_end = self.current_page + self.pager_count_half + 1

        page_html_list = []
        # 添加前面的nav和ul标签
        page_html_list.append('''
                    <nav aria-label='Page navigation>'
                    <ul class='pagination'>
                ''')
        first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
        page_html_list.append(first_page)

        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
        else:
            prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)

        page_html_list.append(prev_page)

        for i in range(pager_start, pager_end):
            if i == self.current_page:
                temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
            else:
                temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
            page_html_list.append(temp)

        if self.current_page >= self.all_pager:
            next_page = '<li class="disabled"><a href="#">下一页</a></li>'
        else:
            next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
        page_html_list.append(next_page)

        last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
        page_html_list.append(last_page)
        # 尾部添加标签
        page_html_list.append('''
                                           </nav>
                                           </ul>
                                       ''')
        return ''.join(page_html_list)

2.views.py

from utils.mypage import Pagination
def ab_pl(request):
    # 分页
    book_queryset = models.Book.objects.all()
    current_page = request.GET.get('page', 1)
    all_count = book_queryset.count()
    # 1.传值生成对象
    page_obj = Pagination(current_page=current_page, all_count=all_count)
    # 2.直接对总数据进行切片操作
    page_queryset = book_queryset[page_obj.start:page_obj.end]
    return render(request, 'ab_pl.html', locals())

3.ap_pl.html

{% for book in page_queryset %}
    <p>{{ book.title }}</p>
{% endfor %}
{{ page_obj.page_html|safe }}
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值