首页 > 其他分享 >day07

day07

时间:2023-05-09 09:37:34浏览次数:24  
标签:day07 self request json html pager page

Ajax基本操作

# 基于上面的图书管理系统环境继续学习
'''特点:异步提交,局部刷新'''
Ajax是js自带的功能,不是一门新的技术点,我们学习的是jQuery封装之后的版本
1.基础语法
	$.ajax({
        url:'',	控制数据的提交地址,等价于form表单的action参数
        type:'',	控制请求方式(默认get请求,小写)
        data:{},	组织提交的数据
        success:function(形参){
            异步回调函数
        }
    })
案例:
1.在app01的urls.py中添加路由
    path('abAjax/', views.ab_ajax)
2.在app01的views.py中添加
def ab_ajax(request):
    return render(request, 'abAjax.html')
3.在templates中创建abAjax.html,在body中添加
    <form action="" method="post">
        <input type="text">+<input type="text">=<input type="text">
        <input type="submit" value="计算">
    </form>
4.启动Django,浏览器输入 127.0.0.1:8000/bms/abAjax
	输入值,并点击计算,发现整个页面都会刷新,刷新之后是新页面,之前输入的数据页没了

解决:
1.abAjax.html,修改body
<input type="text" id="d1">+<input type="text" id="d2">=<input type="text" id="d3">
<input type="submit" value="计算" id="subBtn">

<script>
    $('#subBtn').click(function () {
        // 朝后端发送数据,使用Ajax
        $.ajax({
            url: '', //等价于form表单的action参数
            type: 'post', //等价于form表单的method参数
            data: {'i1': $('#d1').val(), 'i2': $('#d2').val()},//要发送给后端的数据
            success: function (args) { // 形参args就是用于接收后端返回的数据
                //后端接收到了请求,并且给出了一定的反馈
                $('#d3').val(args)
            }
        })
    })
    $('#d2').blur(function () { // 给d2输入框设置失去焦段的操作
        $.ajax({
            url: '', //等价于form表单的action参数
            type: 'post', //等价于form表单的method参数
            data: {'i1': $('#d1').val(), 'i2': $('#d2').val()},//要发送给后端的数据
            success: function (args) { // 形参args就是用于接收后端返回的数据
                //后端接收到了请求,并且给出了一定的反馈
                $('#d3').val(args)
            }
        })
    })
</script>
2.修改views.py的ab_ajax
def ab_ajax(request):
    if request.method == 'POST':
        i1 = request.POST.get('i1')
        i2 = request.POST.get('i2')
        res = int(i1) + int(i2)
        return HttpResponse(res)
    return render(request, 'abAjax.html')
3.启动Django,浏览器输入 127.0.0.1:8000/bms/abAjax
	输入值,点击计算之后,页面是局部刷新,并且第三个框显示计算结果;或者输入值之后,当第二个框失去焦点(鼠标随便点击其他地方),计算结果也能自动显示

数据编码格式

案例:
打开谷歌浏览器的F12,再次输入值,点击计算,在network这一栏
Resquest Headers中
	Content-Type: application/x-www-form-urlencoded; charset=UTF-8

Content-Type
	'''格式1:urlencoded(Ajax默认的编码格式,form表单和Ajax都能实现)'''
    	数据格式: name=jason&pwd=123&hobby=read
        Django后端统一处理到request.POST中
	'''格式2:formdata(form表单和Ajax都能实现)'''
    	数据格式:无法查阅,二进制
        Django后端自动将文件数据处理到request.FILES,普通数据处理到request.POST中
	'''格式3:application/json(form表单发不了,只有Ajax可以)'''
    	数据格式:json格式
        Django后端不会处理,在request.body中存储(bytes类型),需要自己处理
        '''语法注意事项'''html页面使用Ajax的时候,json格式要改成下面2个
            data: JSON.stringify({'name': 'jason', 'pwd': 123}),
            contentType: 'application/json',
格式3:json的案例
1.abAjax.html,修改body
<button id="d1">点我</button>
<script>
    $('#d1').click(function () {
        $.ajax({
            url: '',
            type: 'post',
            data: JSON.stringify({'name': 'jason', 'pwd': 123}),
            contentType: 'application/json',
            success:function (args){

            }
        })
    })
</script>
2.修改views.py的ab_ajax
def ab_ajax(request):
    if request.is_ajax():
        if request.method == 'POST':
            print(request.body)  # b'{"name":"jason","pwd":123}'
            json_bytes = request.body
            import json
            json_dict = json.loads(json_bytes)
            print(json_dict, type(json_dict))  # {'name': 'jason', 'pwd': 123} <class 'dict'>
    return render(request, 'abAjax.html')
3.启动Django,浏览器输入 127.0.0.1:8000/bms/abAjax 点击'点我'按钮
	浏览器上看到的格式是Content-Type: application/json
    pycharm上的打印的是步骤2里的注释内容

ajax携带文件数据

1.abAjax.html,修改body
<input type="text" id="d1">
<input type="file" id="d2">
<button id="d3">点我</button>
<script>
    $('#d3').click(function () {
        // 1.产生内置对象
        let formData = new FormData();
        // 2.添加普通数据
        formData.append('username', $('#d1').val())
        // 3.添加文件数据
        formData.append('file', $('#d2')[0].files[0])
        // 4.发送Ajax请求
        $.ajax({
            url: '',
            type: 'post',
            data: formData,
            contentType: false,//不使用任何编码
            processData: false,//不处理数据对象
            success: function (args) {

            }
        })
    })
</script>
2.修改views.py的ab_ajax
def ab_ajax(request):
    if request.is_ajax():
        if request.method == 'POST':
            print(request.POST) # <QueryDict: {'username': ['jason']}>
            print(request.FILES) # <MultiValueDict: {'file': [<InMemoryUploadedFile: text.txt (text/plain)>]}>
    return render(request, 'abAjax.html')
3.启动Django,浏览器输入 127.0.0.1:8000/bms/abAjax 输入jason,选择text.txt文件,再点击'点我'按钮
	pycharm上的打印的是步骤2里的注释内容

回调函数

"""后端跟Ajax交互,不应该再返回页面,通常情况下都是返回json格式数据"""
'''前端针对HttpResponse和JsonResponse返回的json格式数据处理策略不同'''
	前者不会自动反序列化,后者会自动反序列化
    如果想让前者也自动反序列化,可以在Ajax添加一个固定的参数dataType:'JSON',
    
# 使用了Ajax之后,后端返回的数据由Ajax回调函数里代码决定,
案例:
1.abAjax.html,修改body
            success: function (args) {
                alert(args)
                window.location.href = args # 使用BOM实现跳转页面
            }
2.修改views.py的ab_ajax,添加个return返回值
def ab_ajax(request):
    if request.is_ajax():
        if request.method == 'POST':
            print(request.POST)
            print(request.FILES)
            return HttpResponse('https://www.baidu.com/') # 此处用redirect没用,由Ajax的回调函数决定
    return render(request, 'abAjax.html')


# 后端返回了json格式之后,前端需要收到的是string格式,我们需要转成json格式
'''第一种方案,后端使用json模块,前端转换json格式'''
案例:
1.abAjax.html,修改body
            success: function (args) {
                console.log(typeof args) //string
                console.log(args) //{"name": "jason", "pwd": 123} 只是字符串格式
                let MyBaby = JSON.parse(args)
                console.log(typeof MyBaby) // object
                console.log(MyBaby) //{name: 'jason', pwd: 123} json格式
                console.log(MyBaby.name) //jason
2.修改views.py的ab_ajax,修改return返回值,需要先导入impor json
            return HttpResponse(json.dumps({'name': 'jason', 'pwd': 123}))
'''第二种方案,后端使用JsonResponse,前端直接使用'''
案例:
1.abAjax.html,修改body
            success: function (args) {
                console.log(typeof args) // object
                console.log(args) //{name: 'jason', pwd: 123} json格式
2.修改views.py的ab_ajax,修改return返回值,需要先from django.http import JsonResponse
            return JsonResponse({'name': 'jason', 'pwd': 123})
'''第三中方案,后端使用json模块,前端使用dataType参数'''
1.abAjax.html,修改body
            dataType:'JSON',
            success: function (args) {
                console.log(typeof args) // object
                console.log(args) //{name: 'jason', pwd: 123} json格式
2.修改views.py的ab_ajax,修改return返回值,需要先导入impor json
            return HttpResponse(json.dumps({'name': 'jason', 'pwd': 123}))

sweetaliter介绍

# 关于前端 二次确认框的样式
官网 https://sweetalert.js.org/guides/
使用CDN <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
	在html的script里参考官网的说明
修改图书管理系统的删除二次确认弹窗案例
1.修改booklist.html
	<a href="#" class="btn btn-danger btn-xs delBtn">删除</a>
    ...
    {% block js %}
        <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
        <script>
            $('.delBtn').click(function () {
                swal({
                    title: "你真的要删除吗",
                    text: "如果真的要删了,你要G",
                    icon: "warning",
                    buttons: ["取消", "确认"],
                    dangerMode: true,
                })
                    .then((willDelete) => {
                        if (willDelete) {
                            swal("6!你把书删了", {
                                icon: "success",
                            });
                        } else {
                            swal("还好你没删");
                        }
                    });
            })
        </script>
    {% endblock %}

序列化组件

#  基于上面的图书管理系统环境继续学习
需求:返回json格式的书籍信息
案例:
1.修改app01的urs.py
    # 接口url
    path('getBook', views.get_book),
2.修改views.py
def get_book(request):
    book_query = models.Book.objects.all()
    # 将数据全部构造成json格式{'pk':1,'title':'书'}
    from django.core import serializers
    res = serializers.serialize('json', book_query)
    return HttpResponse(res)
3.浏览器访问 127.0.0.1:8000/bms/getBook

批量操作数据

# 创建新Django项目,项目名day62,应用名app01
需求:浏览器访问一个Django路由,立刻创建10万条数据并展示到前端页面
涉及到大批量数据的创建,直接使用create可能会造成数据库崩溃
	批量数据创建>>>:bulk_create()

案例:
1.models.py中创建数据库
class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name='书名')
2.执行数据库迁移
	makemigrations和migrate
3.urs.py中添加路由
from app01 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    # 批量数据操作
    path('index/',views.index),
]
4.views.py中添加
def index(request):
    book_list = []
    for i in range(100000):
        book_obj = models.Book(title=f'第{i}本书')
        book_list.append(book_obj)
    # 也可以用列表生成式
    # [models.Book(title=f'第{i}本书') for i in range(10000)]
    models.Book.objects.bulk_create(book_list)  # 批量创建数据
    # models.Book.objects.bulk_update() # 批量修改数据
    book_query = models.Book.objects.all()
    return render(request, 'booklist.html', locals())
5.templates创建booklist.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {% load static %}
    <script src="{% static 'jquery.js' %}"></script>
    <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
    <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            {% for book_obj in book_query %}
                <p>{{ book_obj.title }}</p>
            {% endfor %}

        </div>
    </div>
</div>
</body>
</html>
6.浏览器访问 127.0.0.1:8000/index

自定义分页器

1.在app01目录下创建utils或者plugins 该目录一般放置第三方插件
2.在该目录下创建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)
3.修改settings.py
    在最后一行添加
    # 每页展示多少条数据
    PER_PAGE_NUM = 10
4.修改views.py
def index(request):
    from app01.utils import mypage
    current_page = request.GET.get('page', 1)
    book_query = models.Book.objects.all()  # 支持切片
    from django.conf import settings
    per_page_num = settings.PER_PAGE_NUM
    page_obj = mypage.Pagination(
        current_page=current_page,
        all_count=book_query.count(),
        per_page_num=per_page_num,
        pager_count=11)
    page_query = book_query[page_obj.start:page_obj.end]
    return render(request, 'booklist.html', locals())
5.修改templates的booklist.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {% load static %}
    <script src="{% static 'jquery.js' %}"></script>
    <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
    <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            {% for book_obj in page_query %}
                <p class="text-center">{{ book_obj.title }}</p>
            {% endfor %}
            {{ page_obj.page_html|safe }}

        </div>
    </div>
</div>
</body>
</html>
6.启动Django,浏览器访问http://127.0.0.1:8000/index

标签:day07,self,request,json,html,pager,page
From: https://www.cnblogs.com/ycmyay/p/17383811.html

相关文章

  • 算法学习day07哈希表part02-454、383、15、18
    packageLeetCode.hashpart02;importjava.util.HashMap;importjava.util.Map;/***454.四数相加II*给你四个整数数组nums1、nums2、nums3和nums4,数组长度都是n,请你计算有多少个元组(i,j,k,l)能满足:*0<=i,j,k,l<n*nums1[i]+nums2[j]+nums......
  • Day07-设计模式之桥接模式
    桥接模式介绍桥接模式(BridgePattern)是将实现与抽象放在两个不同的类层次中,使两个层次可以独立改变,保持各部分的独立性以及应对他们的功能扩展。UML类图及角色职责抽象类(Abstraction):定义抽象接口,由聚合关系可知,抽象类中包含一个Implementor类型的对象,它与Implementor......
  • day07-OpenFeign-服务调用
    SpringCloudOpenFeign-服务调用1.OpenFeign介绍https://github.com/spring-cloud/spring-cloud-openfeignOpenFeign是一个声明式WebService客户端,使用OpenFeign让编写WebService客户端更加简单它的使用方法是定义一个服务端口然后在上面添加注解OpenFeign也支持可插拔式......
  • day07 sparksql 生成Physical Plan
     1.案例sqlselectA,Bfromtestdata2whereA>2 对应的执行计划:==AnalyzedLogicalPlan==Project[A#23,B#24]+-Filter(A#23>2)+-SubqueryAliastestdata2+-View(`testData2`,[a#23,b#24])+-SerializeFromObject[knownnotnull(a......
  • 学习记录:day07笔记
    进制转换1、为什么使用二进制、八进制、十六进制?因为目前CPU只能识别高低两种电平,只能对二进制数据进行计算二进制虽然能够直接别计算机识别但是不方便人去书写和记......
  • day07-SpringBoot接收参数相关注解
    SpringBoot接收参数相关注解1.基本介绍SpringBoot接收客户端提交数据/参数会使用到相关注解详解@PathVariable、@RequestHeader、@ModelAttribute、@RequestParam、@Co......
  • day07
    day07面向对象面向对象三大特性:封装、继承、多态类设计技巧1.一定要保证数据私有这是最重要的;绝对不要破坏封装性。2.一定要对数据初始化Java不对局部变量进行初始......
  • day07
    day07面向对象面向对象三大特性:封装、继承、多态类设计技巧1.一定要保证数据私有这是最重要的;绝对不要破坏封装性。2.一定要对数据初始化Java不对局部变量进行初始......
  • Day07-Request&Response
    Request&Response今日目标掌握Request对象的概念与使用掌握Response对象的概念与使用能够完成用户登录注册案例的实现能够完成SqlSessionFactory工具类的抽取1.R......
  • day07 (2023.3.7)
    1.方法小练习: 运行结果:2.方法重载: 3.递归 4.面向对象编程(OOP)  5.类 运行结果: 6.构造方法 7.构造方法的重载 结果循环,进入面向对象。小......