Django之ajax
Posted sima-3
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django之ajax相关的知识,希望对你有一定的参考价值。
一.MTV与MVC(了解)
MTV模型(django):
M:模型层(models.py)
T:templates
V:views
MVC模型:
M:模型层(models.py)
V:视图层(views.py)
C:控制器(Controller) urls.py
本质:django的MTV也是MVC
二. 多对多表三种创建方式:
1.第一种 django orm自动帮我们创建:
class Book(models.Model): name = models.CharField(max_length=32) authors = models.ManyToManyField(to=‘Author‘) class Author(models.Model): name = models.CharField(max_length=32)
2.第二种纯手动创建第三张表 (可新增字段,但不可按orm语句进行查询):
class Book(models.Model): name = models.CharField(max_length=32) class Author(models.Model): name = models.CharField(max_length=32) class Book2Author(models.Model): book = models.ForeignKey(to=‘Book‘) author = models.ForeignKey(to=‘Author‘) info = models.CharField(max_length=32)
3.第三种半自动创建第三张表(可扩展性高,并且能够符合orm查询):
class Book(models.Model): name = models.CharField(max_length=32) # 第三种创建表的方式 authors = models.ManyToManyField(to=‘Author‘,through=‘Book2Author‘,through_fields=(‘book‘,‘author‘)) class Author(models.Model): name = models.CharField(max_length=32) # book = models.ManyToManyField(to=‘Book‘,through=‘Book2Author‘,through_fields=(‘author‘,‘book‘)) class Book2Author(models.Model): book = models.ForeignKey(to=‘Book‘) author = models.ForeignKey(to=‘Author‘) info = models.CharField(max_length=32)
三.前后端传输数据编码格式contentType:
urlencoded 对应的数据格式:name=jason&password=666 后端获取数据:request.POST ps;django会将urlencoded编码的数据解析自动放到request.POST formdata form表单传输文件的编码格式 后端获取文件格式数据:request.FILES 后端获取普通键值对数据:request.POST application/json ajax发送json格式数据 需要注意的点 编码与数据格式要一致
四. ajax (Asynchronous javascript And XML)
1.前端有哪些方式可以朝后端发请求:
浏览器窗口手动输入网址 get请求 a标签的href属性 get请求 form表单 get/post请求(默认是get请求) ajax get/post请求
2.ajax特点:
异步提交
局部刷新
3.ajax基本语法 :
提交的地址(url) 提交的方式(type) 提交的数据(data) 回调函数(success) $(‘#d1‘).click(function () $.ajax( // 提交的地址 url:‘/index/‘, // 提交的方式 type:‘post‘, // 提交的数据 data:‘name‘:‘jason‘,‘password‘:‘123‘, // 回调函数 success:function (data) // data接收的就是异步提交返回的结果 alert(data) )
4.ajax默认传输数据的编码格式也是urlencoded
小练习:
前端:
<input type="text" id="i1">+<input type="text" id="i2">=<input type="text" id="i3">
<button id="d1">加我加我~</button>
<script> $(‘#d1‘).click(function () $.ajax( url: ‘‘, type: ‘post‘, data: ‘i1‘: $(‘#i1‘).val(), ‘i2‘: $(‘#i2‘).val(), success: function (data) $(‘#i3‘).val(data)
#接受到的就是后端res传来的值 ) ) </script>
后端:
def index(request): if request.method == ‘POST‘: i1=request.POST.get(‘i1‘) i2=request.POST.get(‘i2‘) i1=int(i1) i2=int(i2) res=i1+i2 return HttpResponse(res) return render(request,‘index.html‘)
效果:
5.前后端传输数据,数据是什么格式就应该告诉别人是什么格式(数据与编码要一一对应):
a. ajax传输json格式数据:
前端:
<script> $(‘#d1‘).click(function () $.ajax( url:‘‘, // url参数可以不写,默认就是当前页面打开的地址 type:‘post‘, contentType:‘application/json‘, data:JSON.stringify(‘name‘:‘jason‘,‘hobby‘:‘study‘), success:function (data) alert(data) ) ) </script>
后端:
def index(request): if request.method == ‘POST‘: print(request.body) #json格式只有通过request.body才能查看 res=json.loads(request.body.decode(‘utf-8‘)) hobby=res.get(‘hobby‘) print(hobby) return HttpResponse(‘OK‘) #必须返回HttpResponse对象 return render(request,‘index.html‘)
b. ajax传输文件
前端:
<input type="file" name="myfile" id="i1"> <button id="d1">提交~</button> #<button id="d1">选我选我~</button># <script> $(‘#d1‘).click(function () var formdata = new FormData(); // FormData对象不仅仅可以传文件还可以传普通的键值对 formdata.append(‘name‘,‘jason‘); // 获取input框存放的文件 //$(‘#i1‘)[0]由Jquery对象变为js对象 formdata.append(‘myfile‘,$(‘#i1‘)[0].files[0]); $.ajax( url:‘‘, type:‘post‘, data:formdata, // ajax发送文件需要修改两个固定的参数 processData:false, // 告诉浏览器不要处理我的数据 contentType:false, // 不要用任何的编码,就用我formdata自带的编码格式,django能够自动识别改formdata对象 // 回调函数 success:function (data) alert(data) ) ) </script>
后端:
def index(request): if request.method == ‘POST‘: print(request.POST) # 普通的键值对:<QueryDict: ‘name‘: [‘jason‘]> print(request.FILES) # 传文件< MultiValueDict: ‘myfile‘: [ < InMemoryUploadedFile: day17课件.md(application / octet - stream) >] > return HttpResponse(‘OK‘) return render(request,‘index.html‘)
6. form表单与ajax异同点:
1.form表单不支持异步提交局部刷新 2.form表单不支持传输json格式数据
3.form表单与ajax默认传输数据的编码格式都是urlencoded
五.批量插入数据:
1.正常插数据:
前端:
<div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <table class="table table-hover table-bordered table-striped"> <thead> <tr> <th>id</th> <th>name</th> </tr> </thead> <tbody> % for book in book_list % <tr> <td> book.pk </td> <td> book.name </td> </tr> % endfor % </tbody> </table> </div> </div> </div>
后端:
def book2(request): for i in range(100): models.Book2.objects.create(name=‘第%s本书‘%i) book_list=models.Book2.objects.all() return render(request, ‘book2.html‘,locals())
2.批量处理:
def test(request): l = [] for i in range(1000): l.append(models.Book(name=‘第%s本书‘%i)) models.Book.objects.bulk_create(l) book_list=models.Book.objects.all() return render(request, ‘book.html‘,locals())
六.分页器
utils / my_page
class Pagination(object): def __init__(self, current_page, all_count, per_page_num=9, pager_count=11): """ 封装分页相关数据 :param current_page: 当前页 :param all_count: 数据库中的数据总条数 :param per_page_num: 每页显示的数据条数 :param pager_count: 最多显示的页码个数 用法: queryset = model.objects.all() page_obj = Pagination(current_page,all_count) page_data = queryset[page_obj.start:page_obj.end] 获取数据用page_data而不再使用原始的queryset 获取前端分页样式用page_obj.page_html """ 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)
views.py:
from django.shortcuts import render from app01 import models from app01.utils import my_page # Create your views here. def test(request): book_list = models.Book.objects.all() all_count = book_list.count() current_page = request.GET.get(‘page‘,1) page_obj = my_page.Pagination(current_page=current_page,all_count=all_count) page_queryset = book_list[page_obj.start:page_obj.end] return render(request,‘book.html‘,locals())
book.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <table class="table table-hover table-bordered table-striped"> <thead> <tr> <th>id</th> <th>name</th> </tr> </thead> <tbody> % for book in page_queryset % <tr> <td> book.pk </td> <td> book.name </td> </tr> % endfor % </tbody> </table> page_obj.page_html|safe </div> </div> </div> </body> </html>
相关知识点:
all_count = models.Book2.objects.all().count() # 要访问的当前页 current_page = request.GET.get(‘page‘, 1) # 用户不传默认展示第一页 current_page = int(current_page) # 每页展示多少条数据 per_page_num = 10 # 获取总页数 pager_nums,more = divmod(all_count,per_page_num) if more: pager_nums += 1 html = ‘‘ for i in range(1,pager_nums+1): html += ‘<li><a href="?page=%s">%s</a></li>‘%(i,i) # 起始位置 page_start = (current_page-1)*per_page_num # 终止位置 page_end = current_page*per_page_num book_list = models.Book2.objects.all()[page_start:page_end] return render(request,‘booklist.html‘,locals())
以上是关于Django之ajax的主要内容,如果未能解决你的问题,请参考以下文章