1.Ajax

1.AJAX:不是新的编程语言,而是一种使用现有标准的新方法,我们目前学习的是jQuery版本。特点:异步提交,局部刷新。

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

3.基本语法
$.ajax({
url:'', // 后端地址 三种填写方式 与form标签的action一致
type:'post', // 请求方式 默认也是get
data:{'v1':v1Val, 'v2':v2Val}, // 发送的数据
success:function (args) { // 后端返回结果之后自动触发 args接收后端返回的数据
$('#d3').val(args)
}
}) """
作业:设置一个注册小程序,用户名不能为jason并且密码不能为123或123456,不能用户点击提交就应该显示:
思路:jQuery事件,ajax事件
register.html:
<body>
<form action="" method="post">
<p>username:
<input type="text" id="i1" name="username">
<span id="s1" style="color: red"></span>
</p>
<p>password:
<input type="text" id="i2" name="password">
<span id="s2" style="color: red"></span>
</p>
<input type="submit" id="i3">
</form>
<script>
$('#i1').blur(function () {
$.ajax({
url:'',
type:'post',
data: {'i1':$('#i1').val()},
success:function (args) {
$('#s1').text(args)
}
})
})
$('#i2').blur(function () {
$.ajax({
url:'',
type: 'post',
data:{'i2':$('#i2').val()},
success:function (args) {
$('#s2').text(args)
}
})
})
</script>
</body> views.py:
def register(request):
if request.method == 'POST':
username = request.POST.get('i1')
password = request.POST.get('i2')
if username:
if username == 'jason':
return HttpResponse('用户名不能为jason')
else:
return HttpResponse('')
if password:
if password == '123' or password == '123456':
return HttpResponse('密码过于简单,请重新输入')
else:
return HttpResponse('')
return render(request, 'register.html') urls.py:
urlpatterns = [
path('register/',views.register)
] 作业2:在前端编写三个输入框,前两个输入框让用户输入数字,点击按钮之后第三个输入框自动返回两数之和:
views.py:
def index(request):
if request.method == 'POST':
i1 = request.POST.get('i1')
i2 = request.POST.get('i2')
i3 = int(i1) + int(i2)
return HttpResponse(i3)
return render(request,'index.html') index.html:
<body>
<input type="text" id="i1"> + <input type="text" id="i2"> = <input type="text" id="i3">
<input type="submit" value="点我发送ajax请求" id="sub">
<script>
$('#sub').click(function () {
$.ajax({
url:'',
type:'post',
data:{
'i1':$('#i1').val(),
'i2':$('#i2').val()
},
success:function (args) {
$('#i3').val(args)
}
})
})
</script>
</body> 作业3:编写一个可以实时校验用户名的输入框,如果用户名为jason,用户色自提提示。 不能点击或者失焦才实现:
# input实时监听事件,ajax时间 register.html:
<body>
<p>username:
<input type="text" name="username" id="username">
<span style="color: red" id="s1"></span>
</p>
<p>password:
<input type="password" name="password" id="password">
<span style="color: red" ></span>
</p>
<script>
$('#username').on('input',function () {
$.ajax({
url:'',
type:'post',
data:{'i1':$('#username').val()},
success:function (args) {
$('#s1').text(args)
}
})
})
</script>
</body> views.py:
def register(request):
if request.method == 'POST':
username = request.POST.get('i1')
if username:
if username == 'jason':
return HttpResponse('用户名不能为jason')
else:
return HttpResponse('')
return HttpResponse('')
return render(request,'register.html')
"""

2.Content-Type

1.urlencoded
ajax默认的编码格式、form表单默认也是
数据格式 xxx=yyy&uuu=ooo&aaa=kkk
django后端会自动处理到request.POST中,用request.POST.get('xxx')拿到值

2.formdata
django后端针对普通的键值对还是处理到request.POST中 但是针对文件会处理到request.FILES中。
"""
系统会根据不同的content-Type来分辨有几种文件类型,需要几个request。
"""

3.application/json:发送json格式数据类型
form表单不支持 ajax可以
<script>
$('#d1').click(function () {
$.ajax({
url:'',
type:'post',
data:JSON.stringify({'name':'jason','age':18}), // 千万不要骗人家
contentType:'application/json', //要指定contentType
success:function (args) {
alert(args)
} })
})
</script>
后端需要从request.body中获取并自己处理
"""
views.py:
import json
def jsonfunc(request):
if request.method == 'POST':
data = request.body # b'{"name":"max","age":25}'
userdict = json.loads(data) # loads自带将二进制转为十进制功能
print(userdict) # {'name': 'max', 'age': 25}
return HttpResponse('成功成功')
return render(request,'jsonfunc.html') jsonfunc.html:
<body>
<button id="b1">点我用ajax发送json数据</button>
<script>
$('#b1').click(function () {
$.ajax({
url:'',
type:'post',
data:JSON.stringify({'name':'max','age':25}),
contentType:'application/json',
success:function (args) {
alert(args)
}
})
})
</script>
</body>
"""

3.ajax携带文件数据

<script>
$('#d3').click(function () {
// 1.先产生一个FormData对象
let myFormDataObj = new FormData();
// 2.往该对象中添加普通数据
myFormDataObj.append('name', 'jason');
myFormDataObj.append('age', 18);
// 3.往该对象中添加文件数据
myFormDataObj.append('file', $('#d2')[0].files[0])
// 4.发送ajax请求
$.ajax({
url:'',
type:'post',
data:myFormDataObj, // ajax发送文件固定的两个配置
contentType:false,
processData:false,
success:function (args){
alert(args)
} })
})
</script>
"""
getfile.html:
<body>
<input type="file" id="i1">
<input value="通过ajax发送文件" id="i2">
<script>
$('#i2').click(function () {
let myFormDataObj = new FormData();
myFormDataObj.append('name','max');
myFormDataObj.append('age',18);
myFormDataObj.append('file',$('#i1')[0].files[0])
$.ajax({
url:'',
type:'post',
data:myFormDataObj,
contentType:false,
processData:false,
success:function (args) {
alert(args)
}
})
})
</script>
</body> views.py:
def getfile(request):
if request.method == 'POST':
print(request.POST) # <QueryDict: {'name': ['max'], 'age': ['18']}>
print(request.FILES) # <MultiValueDict: {'file': [<TemporaryUploadedFile: Capture001.png (image/png)>]}>
return HttpResponse('成功')
return render(request,'getfile.html')
"""

4.ajax补充说明

1.后端print(request.isajax)可以判断当前请求是否由ajax发出。

2.后端返回的三板斧都会被args接收不再影响整个浏览器页面:
返回一个页面被args接收,同理,返回字典根本就不会被接收:

3.选择使用ajax做前后端交互时,后端一般返回的都是json格式的字典数据,当我们从前端打印出来时发现它是一个字符类型,这也就意味着它不能通过点的方式取值:
views.py:
def ajax1(request):
if request.is_ajax():
userdict = {'code':10000 ,'name':'max', 'age':25}
import json
user_data = json.dumps(userdict)
return HttpResponse(user_data)
return render(request,'ajax1.html') ajax1.html:
<body>
<button id="d1">发送ajax请求</button>
<script>
$('#d1').click(function () { # 点击一次就发送一个ajax请求
$.ajax({
url: '',
type: 'post',
data: {'name':'max'},
success:function (args) {
console.log(args)
console.log(typeof args)
}
})
})
</script>
</body>

我们可以在$.ajax的字典中增加一个键值对:dataType:'json',这样前端就可以自动将字符串反序列化称为自定义对象。
views.py:
def ajax1(request):
if request.is_ajax():
userdict = {'code':10000 ,'name':'max', 'age':25}
import json
userdata = json.dumps(userdict)
return HttpResponse(userdata)
return render(request,'ajax1.html') ajax1.html:
<body>
<button id="d1">发送ajax请求</button>
<script>
$('#d1').click(function () {
$.ajax({
url: '',
type: 'post',
data: {'name':'max'},
dataType:'json',
success:function (args) {
console.log(args)
console.log(typeof args)
console.log(args.name)
}
})
})
</script>
</body> 4.此外还有一种方式:我们在后端用JsonResponse模块发送字典,在前端本身就是一个自定义对象,可以直接通过点的方式取值。
views.py:
def ajax1(request):
if request.is_ajax():
userdict = {'code':10000 ,'name':'max', 'age':25}
from django.http import JsonResponse
return JsonResponse(userdict)
return render(request,'ajax1.html') ajax1.html:
<body>
<button id="d1">发送ajax请求</button>
<script>
$('#d1').click(function () {
$.ajax({
url: '',
type: 'post',
data: {'name':'max'},
success:function (args) {
console.log(args)
console.log(typeof args)
console.log(args.name)
}
})
})
</script>
</body>

5.多对多三种创建方式

1.全自动创建(需要创建外键字段,系统会根据外键自动创建第三张表):
class Book(models,Model):
title = models.CharField(max_length=32)
authors = models.ManyToManyField(to='Author') class Author(models.Model):
name = models.CharField(max_length=32)
'''
优势:自动创建第三张表,并且提供了add,remove,set,clear四种操作发方法。
劣势:字段固定,没办法扩展更多的字段
''' 2.纯手动创建(不需要创建外键,第三张表自己创建,可以扩展更多字段):
class Book(models.Model):
title = 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')
others = models.CharField(max_length=32)
join_time = models.DateField(auto_now_add=True)
优势:第三张表完全由自己创建 扩展性强
劣势:编写繁琐 并且不再支持add、remove、set、clear以及正反向概念
'''没有外键,意味着第三幢表的关系需要自己添加,并且不好判断是正向还是反向查询''' 3.半自动创建():
class Book(models.Model):
title = 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)
class Book2Author(models.Model):
book = models.ForeignKey(to='Book', on_delete=models.CASCADE)
author = models.ForeignKey(to='Author', on_delete=models.CASCADE)
others = models.CharField(max_length=32)
join_time = models.DateField(auto_now_add=True)
优势:第三张表完全由自己创建,扩展性强 正反向概念依然清晰可用
劣势:编写繁琐不再支持add、remove、set、clear

6.django自带的序列化组件

1.前后端分离的项目,只需要返回json格式的数据即可。

将所有的书籍信息放在一个大字典内,然后返回给前端:
def ajax2(request):
book_queryset = models.Book.objects.all()
data_dict = {}
for book_obj in book_queryset:
tem_dict = {}
tem_dict['pk'] = book_obj.pk
tem_dict['title'] = book_obj.title
tem_dict['price'] = book_obj.price
tem_dict['info'] = book_obj.info
data_dict[book_obj.pk] = tem_dict
return JsonResponse(data_dict, json_dumps_params={'ensure_ascii':False}) 2.上述结果我们可以直接用序列化组件serializers实现,serializers可以直接将queryset转成json格式发给前端并且前端还拥有自定义对象的特性。
def ajax2(request):
book_queryset = models.Book.objects.all()
from django.core import serializers
res = serializers.serialize('json', book_queryset)
return HttpResponse(res)
"""
但是拿到的结果是编码过后的结果,需要在BEJSON中查看解码之后的结果
"""

7.批量操作数据

1.如果想在一张表中插入100000条数据,我们的思路如下:
views.py:
def ajax4(request):
for i in range(1,10000)
models.Book.objects.create(title='第%s本书'%i,info='很带劲',price=888.88)
book_queryset = models.Book.objects.all()
return render(request,'ajax4.html',locals()) html.py:
<body>
<p>
{% for book_obj in book_queryset %}
{{ book_obj.title }}
{% endfor %}
</p>
</body> 2.如果添加的数据很多,并且数据之间有规律,我们可以采用bulk_create插入:
views.py:
def ajax5(request):
book_obj_list = [] # 1.首先生成一个空列表
for i in range(100000):
book_obj = models.Users(name='max',country='china')
book_obj_list.append(book_obj) # 2.生成100000个空对象并且添加到列表中
models.Users.objects.bulk_create(book_obj_list) # 3.直接将列表当做参数传入表中
return HttpResponse('数据传输中...')

8.自定义分页器模块

"""
分页器代码流程推导参考:
https://www.cnblogs.com/Dominic-Ji/articles/12035722.html
"""
自定义分页器代码封装:
1.在应用下新建一个目录utils,在该目录下新建一个py文件,命名为:myPage.py:
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) 2.views.py:
def page(request):
friend_queryset = models.Friend.objects.all()
from app01.utils.myPage import Pagination
current_page = request.GET.get('page')
'''可以在这里设置每页展业数据条数,页数'''
page_obj = Pagination(current_page=current_page,all_count=friend_queryset.count(),per_page_num=20,pager_count=7)
page_queryset = friend_queryset[page_obj.start:page_obj.end]
return render(request,'page.html',locals()) page.html:
{% for friend_obj in page_queryset %}
<p style="text-align: center">{{ friend_obj.name }}</p>
{% endfor %}
<div class="text-center">{{ page_obj.page_html|safe }}</div>
</body>

最新文章

  1. 背水一战 Windows 10 (28) - 控件(文本类): TextBox, PasswordBox
  2. Windows程序设再读笔记00-序言
  3. C++/CLI——读书笔记《Visual C++/CLI从入门到精通》 第Ⅳ部分
  4. 我的开发框架之ORM框架
  5. linux 配置java 环境
  6. 关于Web项目里的给表单验证控件添加结束时间不得小于开始时间的验证方法,日期转换和前台显示格式之间,还有JSON取日期数据格式转换成标准日期格式的问题
  7. sphinx 源码阅读之分词,压缩索引,倒排——单词对应的文档ID列表本质和lucene无异 也是外部排序再压缩 解压的时候需要全部扫描doc_ids列表偏移量相加获得最终的文档ID
  8. [JQuery EasyUI系列]简介
  9. mysql 数据库封装类:返回索引、关联、字符串数组;分页查询封装类 :$page=new Page(表的总条数,每页的条数);$sql = &quot;&quot;.$page-&gt;limit; echo $page-&gt;fpage();
  10. Hadoop:Task process exit with nonzero status of 1 异常
  11. Sonar相关汇总
  12. EF调用sp,EF自动生成返回类型
  13. 在Java 线程中返回值的用法
  14. xargs - 地下管道
  15. mysql:ip地址连接
  16. JS查错小工具-三生有幸【推荐】
  17. 【转】嵌入式C语言调试开关
  18. 微信小游戏爆款秘笈 数据库MongoDB攻略篇
  19. [SimplePlayer] 3. 视频帧同步
  20. 微信小程序新闻信息列表展示

热门文章

  1. 这是不是你想要了解SQL的艺术,基础语法等等
  2. git pull与git pull --rebase
  3. Vue3 企业级优雅实战 - 组件库框架 - 4 组件库的 CSS 架构
  4. Kubernetes集群YAML文件详解
  5. XTDrone和PX4学习期间问题记录(一)
  6. Kubernetes介绍和资源管理
  7. 【云原生 · Kubernetes】apiserver高可用
  8. 关于Go你不得不知道的小技巧
  9. 一文详解GaussDB(DWS) 的并发管控和内存管控
  10. 万字长文!对比分析了多款存储方案,KeeWiDB最终选择自己来