day11 ajax实现删除提醒(普通版、进阶版)ajax发送文件 核心参数值dataType 自定义分页器

day11 ajax实现删除提醒(普通版、进阶版)ajax发送文件 核心参数值dataType 自定义分页器

昨日内容复习

图书管理系统

#图书管理系统
首页展示功能
	1.在后端查全部的数据对象 返回一个展示页面 并把数据对象传给展示页面
    2.展示页面查询出全部的数据对象,展示页面
添加图书功能
	1.创建添加图书页面的urls views返回一个添加html页面 
    2.html页面获取输入的数据 传给后端 
    3.后端判断是post请求 把数据拿过来写入到数据库 并重定向展示页面
编辑图书功能
	1.将用户要编辑的数据主键值发送给后端
    2.后端查询出相应的数据对象并返回一个编辑页面
    3.在该编辑页面展示出待编辑对象的原始数据
    4.用户修改完数据发送给后端 post请求
    5.后端获取并修改相应的数据
删除功能
	1.用户想要删除的数据主键值发送给后端
    2.后端拿到主键值直接删除
    

choices参数

  • 多对多三种创建方式

    1.全自动
    	models.ManyToManyField(to='Author')
    2.纯手动
    	自己创建第三张关系表 不使用ManyToManyField字段
    3.半自动
    	models.ManyToManyField(to='Author',
                              through=''
                              through_fileds=()
                              )
    
  • MTV与MVC模型

    # 主要用于描述web框架的主要结构
    django自称为MTV框架 其实本质也还是MVC框架
    
  • ajax基本语法结构

    # 异步提交 局部刷新
    '''基于jQuery的版本(务必要先导入jQuery)'''
    $.ajax({
        url:'',  # 控制提交的路径 三种书写格式
        type:'',  # 控制提交的方法 get/post/put/delete/options...
        data:'',  # 控制提交的数据(可有可无)
        success:function(args){
            # 异步回调机制
        }
    })
    
  • content-Type参数

    content-Type在请求头中 用于标识数据的编码格式 django针对不同编码格式的数据处理策略有所不同
    
    针对urlencoded格式 自动处理到request.POST中
    针对formdata格式 自动区分普通数据和文件数据分别处理到request.POST与request.FILES
    针对json格式 django后端不做任何的处理 直接放在request.body中
    
  • ajax发送json格式数据(言行合一)

    $.ajax({
        url:'',  # 控制提交的路径 三种书写格式
        type:'',  # 控制提交的方法 get/post/put/delete/options...
        data:JSON.stringify(数据),  # 控制提交的数据(可有可无)
        contentType:'application/json'
        success:function(args){
            # 异步回调机制
        }
    })
    

今日内容概要

  • ajax实现删除二次提醒(普通版本)

  • ajax结合第三方插件sweetalert实现二次提醒(样式好看些)

  • ajax如何发送文件数据

  • ajax核心参数之dataType

  • django序列化组件(自带的)

  • 自定义分页器(django自带一个分页器只不过不好用)

  • 自定义分页器的固定使用方式

今日内容详细

  • ajax实现删除二次提醒(普通版本)

    #如果想使用ajax和后端做交互,就不要用以前的交互方式了 以前的a的href的get请求
    #html页面 id标签不能重复   class可以重复 所以给删除一个class 
    #标签支持自定义属性   普通版本 
    --------------------------------------------------------------------------------
    #ajax删除页面
    url(r'^del_book',views.delete_book)
    
    
    
    --------------------------------------------------------------------------------
    #boo_show.html
    					#删除标签#
    <a class="btn btn-danger btn-xs c1" delete_id="{{ book_obj.pk }}">删除</a>
                            <!--标签既可以有默认的属性也可以有自定义的属性-->
     --------------------------------------------------------------------------------
    {% block js %}
        <script>
            let $btn=$('.c1');
            $btn.on('click',function () {
                var delete_id=$(this).attr('delete_id')  //$(this)指的是当前操作对象  attr 拿某个标签内部属性
                var $this=$(this)   //语法可能有冲突 在这声明下面直接用
    
                //1.先做提醒
                let res=confirm('确定删除吗')
                if (res){
                    //2.点了确定 发送ajax请求
                    $.ajax({
                        url:'/del_book/',
                        type:'post',
                        data: {'delete_id':delete_id}, //传的参数
                        success:function (args) {
                            alert(args)
                            window.location.reload()//刷新页面 第一种方式但是会有问题
                            //js代码自动刷新 第二种方式  上面定义了$this=$(this)
                            //删除当前操作对象的父标签的父标签
                            $this.parent().parent().remove()
    
                        }
    
                    })
                }else {
                    alert('不敢吧 !!')
                }
            })
    
    
        </script>
    {% endblock %}
    --------------------------------------------------------------------------------    
    def delete_book(request):
        #判断当前请求是否是ajax请求
        if request.is_ajax():
            if request.method=='POST':
                delete_id=request.POST.get('delete_id')
                models.Book.objects.filter(pk=delete_id).delete()
                return HttpResponse('删除成功!!!!!!!')
    
  • ajax结合第三方插件sweetalert实现二次提醒(样式好看些)

    //引入cdn  sweetalert
    <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
    //删除按钮
    <script>
        var $btn=$('.c1');
    
        $btn.on('click',function () {
            var delete_id=$(this).attr('delete_id')
            var $this=$(this);
            swal({
              title: "确定删除吗?",
              text: "删除了就不能恢复了",
              icon: "warning",
              buttons: true,
              dangerMode: true,
            })
            .then((willDelete) => {
              if (willDelete) {
                  //向后端发送ajax请求
                  $.ajax({
                      url:'/del_book/',    //支持反向解析
                      type:'post',
                      data: {'delete_id': delete_id},
                      success:function (args) {
                          $this.parent().parent().remove();
                          swal(args, {
                              icon: "success",
                          });
                      }
    
                  })
    
              } else {
                swal("不敢删吧!!");
              }
            });
        })
        </script>
    
  • ajax如何发送文件数据

    文件数据<input type="file" id="d1">
    普通数据<input type="text" id="d2">
    普通数据<input type="text" id="d3">
    <button id="b1">提交ajax</button>
    
    <script>
    
        $('#b1').click(function () {
            //1.先获取用户输入的数据
            //1.1.ajax发送携带文件数据的请求,需要借助于内置对象FormData
            //1.2定义一个formdata对象
            let formDataObj=new FormData()
            //2.往该对象中添加数据(普通数据,文本数据都可以添加)
            //2.1 格式    ('别名',获取数据的values)
            formDataObj.append('name',$('#d2').val())
            formDataObj.append('pwd',$('#d3').val())
            //文件数据有固定的语法格式   #记住 固定语法
            //                        先找到这个对象索引0 在点files[0]
            formDataObj.append('files',$('#d1')[0].files[0]);
    
            $.ajax({
                url:'/ab_files/',
                type:'post',
                //发送文件需要额外配置的两个参数contentType,processData
                contentType: false,
                processData: false,
    
                data:formDataObj,
                success:function (args) {
                    alert(args)
                }
            })
    
        })
    
    </script>
    
  • ajax核心参数之dataType.

    #前后端交互 如果采用的是ajax,后端的返回值应使用字典样式(json格式的字符串)
    当后端采用HttpResponse返回json格式数据到ajax异步回调函数默认情况下需要我们自己做反序列化
    前端如果不想手动反序列化后端传过来的json格式数据,可以指定dataType:'JSON' 指定后 后端返回给前端的数据如果不是json格式的  他不会反序列化  会自动区分
    # 以后推荐加上 增加程序兼容性
    
    
  • django序列化组件(自带的)

    from django.core import serializers
     #serializers.serializer 直接可以把 queryset套数据对象 转换成json格式的列表套字典 字典里自动加来自于哪个应用下的那个表,主键值 ,表的字段用一个fields做一个字典嵌套  外键什么的也会放在一个字典里
        res=serializers.serialize('json',books_queryset)
        return HttpResponse(res)
    
  • 批量插入数据

    如果大批量创建数据 for循环创建效率极慢
    # 批量插入 推荐
    	#生成器表达式  生产一个new_obj_iter里面存放了好多好多对象
        new_obj_iter=(models.Book(title='第%s本书'%i) for i in range(100000))
        #批量插入bulk_create
        models.Book.objects.bulk_create(new_obj_iter)
        data_queryset=models.Book.objects.all()
        return render(request,'ab_bc.html',locals())
    
  • 分页

    #思路
    1.前端传给后端要看第几页数据 后端获取请求的页数
    2.后端定义页面显示多少数据 起始位置 终止位置 他们是有逻辑关系的
    3.后端通过divmod 获取总共多少页 有余数+1 
    4.后端定义 一个变量=当前页数 判断当前选择的页数小于最小页的中间位置  让这个变量=最小页的中间位置 为了防止左面越界 右面的也设置
    5.后端编写HTML代码 for循环 开始位置-5 结束为止+6  设置超链接 并且选择的列高亮显示
    6.前端接受数据 for循环数据对象 取title 加上一个分页器bootstrap 引用后面的html代码 实现显示十页
    
    
    def ab_bc (request):
        # new_obj_iter=(models.Book(title='第%s本书'%i) for i in range(100000))
        # models.Book.objects.bulk_create(new_obj_iter)
    
    
        current_page=request.GET.get('page',1)#获取页数
        try:
            current_page=int(current_page)
        except Exception:
            current_page=1
        per_page_num=10  #每页展示多少条
        start_page=(current_page-1)*per_page_num #开始行数
        end_page=per_page_num*current_page #结束行数
        #他们三个规律为 start_page=(current_page-1)*per_page_num
        #            开始位置 = (页数-1)*每页展示多少条
    
        #           end_page=current_page*per_page_num
        #            结束为止=页数*每页展示多少条
        all_data = models.Book.objects.all()
        all_page_num, more = divmod(len(all_data),per_page_num )
    
        if more:
            all_page_num+=1
    
        html=''
        xxx=current_page
        if current_page<6:
            xxx=6
        if current_page>all_page_num-6:
            xxx=all_page_num-6
        for i in range(xxx-5,xxx+6):
            if i==current_page:
                tmp='<li class="active"><a href="?page=%s">%s</a></li>'%(i,i)
            else:
                tmp = '<li ><a href="?page=%s">%s</a></li>' % (i, i)
            html+=tmp
    
    
        data_queryset=all_data[start_page:end_page]
    
        return render(request,'ab_bc.html',locals())
    

    自定义分页器

class Pagination(object):
    def __init__(self, current_page, all_count, per_page_num=2, 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)

使用-后端

 def get_book(request):
   book_list = models.Book.objects.all()
   current_page = request.GET.get("page",1)
   all_count = book_list.count()
   page_obj = Pagination(current_page=current_page,all_count=all_count,per_page_num=10)
   page_queryset = book_list[page_obj.start:page_obj.end]
   return render(request,'booklist.html',locals())

使用-前端

<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            {% for book in page_queryset %}
            <p>{{ book.title }}</p>
            {% endfor %}
            {{ page_obj.page_html|safe }}
        </div>
    </div>
</div>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值