zoukankan      html  css  js  c++  java
  • ajax,文件上传,分页器

     

    一.Ajax简介

      AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。

    AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

    优点: ​ AJAX使用Javascript技术向服务器发送异步请求 ​ AJAX无须刷新整个页面

    ajax基本语法:

    1     $.ajax({
    2         url:'/index/',
    3         type:'get',
    4         date:{"name":"shy","pwd":123},
    5         success:function(response){
    6             console.log(response)
    7         }
    8     })

    应用案例:判断用户名是否已经被注册

    二.文件上传

    1.请求头contentType:contentType是指请求体的数据封装格式,常见的类型有三种

    (1).application/x-www-form-urlencoded ​ 此类型是from表单默认的类型,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。 ​ 请求类似于下面这样(无关的请求头在本文中都省略掉了): ​ POST http://www.example.com HTTP/1.1 ​ Content-Type: application/x-www-form-urlencoded;charset=utf-8 ​ user=yuan&age=22 ​ (2).multipart/form-data ​ 这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 <form> 表单的 enctype 等于 multipart/form-data。 ​ 直接来看一个请求示例:

     1 POST http://www.example.com HTTP/1.1
     2 Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
     3 
     4 ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
     5  Content-Disposition: form-data; name="user"
     6 
     7 yuan
     8 ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
     9 Content-Disposition: form-data; name="file"; filename="chrome.png"
    10 Content-Type: image/png
    11 
    12 PNG ... content of chrome.png ...
    13 ------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

    (3).application/json ​ 现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。 ​ 由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify, ​ 服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。

    2.contentType的查看方式

    当前端有一个简单的form表单:

    1 <form action="/text/" method="post">
    2     {% csrf_token %}
    3     姓名<input name="name" type="text">
    4     年龄<input name="age" type="text">
    5     <button>提交</button>
    6 </form>

    后端对应一个相应的处理函数:

    1 def text(request):
    2      print(request.POST)
    3      return HttpResponse('ok')

    运行成功后,我们可以从浏览器的请求头中看到:

    1 Content-Type: application/x-www-form-urlencoded

    3.基于form表单的文件上传

    在模板中:

    1 <form action="/byform/" method="post" enctype="multipart/form-data">
    2      {% csrf_token %}
    3      姓名<input name="user" type="text"><br>
    4      请选择文件 <input name="file" type="file"><br>
    5      <button>提交</button>
    6 </form>

    在视图中:

     1 def byform(request):
     2      print(request.POST)
     3      # < QueryDict: {'csrfmiddlewaretoken': ['9BxiKXnDy4xobLQ9m4QZDHQsOJeiWcCCE0uETorZjgCRZB01oL9evgqBULX2ERY2'],'user': ['alex']} >
     4 
     5      print(request.FILES)
     6      # < MultiValueDict: {'file': [ < InMemoryUploadedFile: IMG20181030152136.jpg(image / jpeg) >]} >
     7 
     8      # 文件对象
     9      file_obj=request.FILES.get('file')
    10 
    11      # 文件对象的name属性,获取文件名称
    12      file_name=file_obj.name
    13       # IMG20181030152136.jpg
    14 
    15      path=os.path.join(BASE_DIR,'media','img',file_name)
    16      with open(path,'wb') as f:
    17          for line in file_obj:
    18               f.write(line)
    19      return HttpResponse('上传成功')

    4.基于ajax的文件上传

    在模板中

     1 <h4>基于ajax的文件上传</h4>
     2         <form >
     3             姓名 <input class="num3" name="user" type="text"><br>
     4             文件 <input class="num4" type="file">
     5             <input type="button" class="btn1" value="提交">
     6         </form>
     7 
     8         $('.btn1').click(function(){
     9             var formdata=new FormData();
    10             formdata.append("num3",$('.num3').val());
    11             formdata.append("num4",$('.num4')[0].files[0]);
    12 
    13             $.ajax({
    14                 url:'/byform/',
    15                 type:'post',
    16                 processData: false ,    // 不处理数据
    17                 contentType: false,
    18                 data:formdata,
    19                 headers:{"X-CSRFToken":$.cookie('csrftoken')},
    20                 success:function(response){
    21                     console.log(response)
    22                 },
    23             })
    24         })

    在视图中

     1 def byform(request):
     2      print(request.POST)
     3      # < QueryDict: {'csrfmiddlewaretoken': ['9BxiKXnDy4xobLQ9m4QZDHQsOJeiWcCCE0uETorZjgCRZB01oL9evgqBULX2ERY2'],'user': ['alex']} >
     4      print(request.FILES)
     5      # < MultiValueDict: {'file': [ < InMemoryUploadedFile: IMG20181030152136.jpg(image / jpeg) >]} >
     6      # 文件对象
     7      file_obj=request.FILES.get('num4')
     8      # 文件对象的name属性,获取文件名称
     9 
    10      file_name=file_obj.name
    11      # IMG20181030152136.jpg
    12 
    13      path=os.path.join(BASE_DIR,'media','img',file_name)
    14      with open(path,'wb') as f:
    15           for line in file_obj:
    16               f.write(line)
    17      return HttpResponse('上传成功')

    三.分页器

    1.批量导入数据

    1 for i in range(100):
    2       book=Book(title="悼念金庸-%s"%i,price=i*i,pub_date='2012-12-12',publish_id=1 )
    3       list.append(book)
    4 Book.objects.bulk_create(list)

    2.分页器语法

     1         paginator=Paginator(book_list,20)
     2         print(paginator.count)  #一共有多少页
     3         print(paginator.num_pages) #分了多少页
     4         print(paginator.page_range)  #每一页的页码
     5         page=paginator.page(5)  #第n页的数据
     6         # for i in page:
     7         #     print(i)
     8         print(page.has_next())  #是否有上一页
     9         print(page.has_previous())   #是否有下一页
    10         print(page.next_page_number())  #上一页的页码
    11         print(page.previous_page_number())   #下一页的页码

    3.实例

    在模板中

     1             <div class="col-md-8 col-md-offset-2">
     2                 <nav aria-label="Page navigation">
     3                   <ul class="pagination">
     4                     {% if page.has_previous %}
     5                     <li><a href="?page={{ page.previous_page_number }}">上一页</a></li>
     6                     {% else %}
     7                     <li class="disabled"><span href="">上一页</span></li>
     8                     {% endif %}
     9 
    10                 {% for num in paginator.page_range %}
    11 
    12                     {% if num == page_num %}
    13                     <li class="active"><a  href="?page={{ num }}">{{ num }}</a></li>
    14                     {% else %}
    15                     <li><a href="?page={{ num }}">{{ num }}</a></li>
    16                     {% endif %}
    17 
    18                 {% endfor %}
    19 
    20                     {% if page.has_next %}
    21                     <li><a href="?page={{ page.next_page_number }}">下一页</a></li>
    22                     {% else %}
    23                     <li class="disabled"><span href="">下一页</span></li>
    24                     {% endif %}
    25                     </ul>
    26                 </nav>
    27                 </div>

    在视图中

    1             paginator = Paginator(book_list, 20)
    2             page_num=int(request.GET.get("page",1) ) #如果取不到,就用1
    3             page=paginator.page(page_num)
    4             return render(request,'index.html',{"book_list":book_list,"paginator":paginator,"page":page,"page_num":page_num})

    功能实现的函数:

     1         class Pagination():
     2             def __init__(self, current_page_num, all_count, request, per_page_num=5, pager_count=11):
     3                 """
     4                 封装分页相关数据
     5                 :param current_page_num: 当前访问页的数字
     6                 :param all_count:    分页数据中的数据总条数
     7                 :param per_page_num: 每页显示的数据条数
     8                 :param pager_count:  最多显示的页码个数
     9                 """
    10                 try:
    11                     current_page_num = int(current_page_num)
    12                 except Exception as e:
    13                     current_page_num = 1
    14                 if current_page_num < 1:
    15                     current_page_num = 1
    16                 self.current_page_num = current_page_num
    17                 self.all_count = all_count
    18                 self.per_page_num = per_page_num
    19                 all_pager, tmp = divmod(all_count, per_page_num)
    20                 if tmp:
    21                     all_pager += 1
    22                 self.all_pager = all_pager
    23                 self.pager_count = pager_count
    24                 self.page_count_half = int((pager_count - 1) / 2)
    25                 import copy
    26                 self.params = copy.deepcopy(request.GET)
    27 
    28             @property
    29             def start(self):
    30                 return int((self.current_page_num - 1) * self.per_page_num)
    31 
    32             @property
    33 
    34             def end(self):
    35                 return int(self.current_page_num * self.per_page_num)
    36 
    37             def page_html(self):
    38                 if self.all_pager<=self.pager_count:
    39                     page_start=1
    40                     page_end=self.all_pager+1
    41                 else:
    42                     if self.current_page_num<=self.page_count_half:
    43                         page_start=1
    44                         page_end=self.pager_count+1
    45                     else:
    46                         if self.current_page_num >(self.all_pager-self.page_count_half):
    47                             page_start=self.all_pager-self.pager_count+1
    48                             page_end=self.all_pager+1
    49                         else:
    50                             page_start=self.current_page_num-self.page_count_half
    51                             page_end=self.current_page_num+self.page_count_half+1
    52                 page_html_list=[]
    53                 first_page='<li><a href="?page=%s">首页</li>' % 1
    54                 page_html_list.append(first_page)
    55                 if self.current_page_num<=1:
    56                     prev_page="<li class='disabled'><a href='#'>上一页</a></li>"
    57                 else:
    58                     prev_page = "<li ><a href='?page=%s'>上一页</a></li>" % (self.current_page_num-1)
    59                 page_html_list.append(prev_page)
    60                 for i in range(page_start,page_end):
    61                     self.params["page"]=i
    62                     if i==self.current_page_num:
    63                         temp="<li class='active'><a href='?%s'>%s</a></li>" % (self.params.urlencode(),i)
    64                     else:
    65                         temp = "<li><a href='?%s'>%s</a></li>" % (self.params.urlencode(), i)
    66                     page_html_list.append(temp)
    67                 if self.current_page_num>=self.all_pager:
    68                     next_page="<li class='disabled'><a href='#'>下一页</a></li>"
    69                 else:
    70                     next_page = "<li ><a href='?page=%s'>下一页</a></li>" % (self.current_page_num+1)
    71                 page_html_list.append(next_page)
    72                 last_page = '<li><a href="?page=%s">尾页</li>' % (self.all_pager)
    73                 page_html_list.append(last_page)
    74                 return "".join(page_html_list)
  • 相关阅读:
    创建onlineworkspace问题仍没解决?
    Javascript 脚本错误.
    从HtmlInputFile控件中读取文件 保存到document libary中.
    Request.Form.Get
    DataGrid 模板列里 寻找所在列的隐藏列的值
    test
    重写ProgressDialog,实现各种个性进度条需求(含源码)
    Android自定义控件实现环形播放进度条
    为你的应用添加悬浮窗功能
    Android 左右滑动 控件
  • 原文地址:https://www.cnblogs.com/shanghongyun/p/9856868.html
Copyright © 2011-2022 走看看