day61 layui和分页原理

昨日内容回顾

choices参数的使用
复制代码
一般用在什么场景:当被存储的字段数据可能被列举完毕的时候一般会使用choices参数
性别  学历  来源 工作经验等
一般情况下不在数据表中直接存储中文,存数字、存字母来做映射
# 怎么使用
gender_choices = (
    (1, '男'),
    (2, '女'),
)
gender = models.IntegerField(choices=gender_choices)
gender_abc_a = models.IntegerField(choices=gender_choices)
# 迁移完数据库之后,在表中存储的还是整型,并且数据的范围有字段类型来决定IntegerField
​
# 读取数据之后,他会自动做个映射关系
print(res.gender) # 还是整型数字
print(res.get_gender_display()) # 显示对应的映射关系
print(res.get_score_display()) # 显示对应的映射关系
print(res.get_gender_abc_display()) # 显示对应的映射关系
MTV模式
复制代码
MVC其实都是把整个项目分层了,一般分三层:M V C  M T V S
多对多的创建方式
复制代码
三种方法
# 全自定
    第三张表自定创建,可以使用add set remove clear,还可以使用正反向的查询
# 全手动
    第三张表有我们自己创建,所有的方法都不能使用了
# 半自动 推荐
    第三张表也是有我们自己创建,但是它可以使用正反向查询
    though='关系表'  though_fields=''
    ManyToManyField()
Ajax技术
复制代码
特征:异步提交、局部刷新
它是前端的技术,它是配合后端来使用的,就是把前端的数据异步提交到后端嘛
应该先学习js版本,分五个步骤
#我们直接学习jQuery版本的Ajax,它帮我们做了封装,用起来更加方便了
首先要引进jQuery文件
如何发起Ajax请求呢
$.ajax({
    url:'',
    type:'',
    data:{},
    success:function(res){
        console.log(typeof res) # 它的类型 str object
    }
})
​
序列化 反序列化

今日内容概要

  • 前后端数据传输的编码格式

  • Ajax提交json格式的数据

  • Ajax提交文件数据

  • Ajax实现弹窗的二次确认

  • 批量增加数据

  • 分页的原理及推导

  • 分页类的使用

  • cookie和session的介绍

  • Django操作cookie、session

今日内容详细

前后端数据传输的编码格式(contentType)
复制代码
我们只研究post请求方式的编码格式
"""
    get请求方式没有编码格式
    index?useranme=&password=
    参数直接在url地址的后面拼接着
    get请求方式没有请求体
"""
​
# 有哪些方式可以提交post请求
form表单
Ajax
api工具
​
# 研究form表单的post请求
默认的编码格式:urlencoded
数据传输的形式:title=dasdas&price=2312&date=&publish=2&authors=3
# 对于Django后端是如何接收数据的:
把提交过来的数据都封装到了request.POST中
​
还可以提交form-data格式的
enctype:form-data # 提交文件数据
数据传输的形式:
title=dasdas&price=2312&date=&publish=2&authors=3
--------------binary-----------------------------
文件数据
​
# 对于Django后端如何接收数据的
普通数据还是在request.POST中
文件数据呢还是在request.FILES中
"""之所以你能够在POST和FILES中接收数据,是因为Django给你封装了,提交过来的数据并不是queryDICT"""
​
# ajax提交post请求
默认情况下,Ajax提交的数据后端还是在request.POST中接收的
默认的编码格式:urlencoded
需要修改contentType类型:json格式的
​
"""对于符合urlencoded格式的数据后端都是在request.POST中接收数据的"""
Ajax提交json格式的数据
复制代码
"""
{"username":"kevin", "password":123}  它不符合urlencoded格式的数据
"""
# 在Django后端肯定在request.POST中接收不到数据
$.ajax({
              url:'',
              type:'post',
              data:JSON.stringify({a:1, b:2}), // 序列化的     "{"a":1, "b":2}"
              contentType:'application/json', // json格式的
              success:function (res) {
​
              }
          })
​
def index(request):
    if request.method == 'POST':
        # request.POST只能接收post请求的符合urlencoded编码格式的数据 {}
        print(request.POST) # <QueryDict: {}>
        print(request.body) # b'{"a":1,"b":2}'
        json_bytes=request.body # 接收浏览器发过来的纯原生的数据,二进制,需要自己做封装处理
        # json_str=json_bytes.decode('utf-8')  # {"a":1,"b":2} <class 'str'>
        # print(json_str, type(json_str))
        import json
        # json_dict = json.loads(json_str)
        # print(json_dict, type(json_dict)) # {'a': 1, 'b': 2} <class 'dict'>
        json_dict=json.loads(json_bytes) # 最好不要省略
        print(json_dict, type(json_dict))  # {'a': 1, 'b': 2} <class 'dict'>
​
    return render(request, 'index.html')
Ajax提交文件数据
复制代码
<script>
    $(".btn").click(function (ev) {
        console.log(123);
        // 要获取到文件数据,
        {#console.log($("#myfile")[0].files[0]) // C:\fakepath\123.png#}
        // 提交文件数据需要借助于formdata对象
        var myFormDataObj = new FormData;
        var username = $("#username").val();
        var myfile = $("#myfile")[0].files[0];
        myFormDataObj.append('username', username);
        myFormDataObj.append('myfile',myfile);
​
        $.ajax({
            url: '',
            type: 'post',
            {#data: JSON.stringify({a: 1, b: 2}), // 序列化的     "{"a":1, "b":2}"#}
            data: myFormDataObj, // 序列化的     "{"a":1, "b":2}"
            {#contentType: 'application/json', // json格式的#}
            contentType:false, // 告诉浏览器不要给我的编码格式做任何的处理
            processData: false, //
            success: function (res) {
​
            }
        })
    })
</script>
Ajax结合layer弹窗实现二次确认
复制代码
https://layuiweb.com/layer/index.htm
批量插入数据
复制代码
    bulk_list = []
    for i in range(10000):
        user_obj=models.UserInfo(username='kevin%s' %i)
        bulk_list.append(user_obj)
    # 循环之后得到了一个列表,10000个对象
    # 数据库的优化, 同样的功能,不同的sql执行的效率差距很大
    # 优化查询速度的时候,首先想到的是,加索引、优化sql语句,有的sql走做引、有的sql不走索引
    models.UserInfo.objects.bulk_create(bulk_list)
分页的原理及推导
复制代码
当查询的数据太多的时候,一页展示不完,分页码展示
​
"""
总数据         每页展示        总页数
100             10              10
101             10              11
99              10              10
怎么计算出来总页数
总数据  /  每页展示  =  总页数
​
有余数+1
没有余数=商
"""
divmod
分页类
复制代码
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
​
    @property
    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)
相关推荐
腾讯TNTWeb前端团队6 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰10 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪10 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪10 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy11 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom11 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom11 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom12 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom12 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom12 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试