zoukankan      html  css  js  c++  java
  • choices参数 MTV与MVC ajax contentType 序列化组件 自定义分页器

    知识点:
    1
    .choice参数 2.MTV 与 MVC 框架 3.ajax 4.contentType前后端传输数据编码格式 5.序列化组件(django自带,小型的):serializers 6.sweetalert 7.自定义分页器

    1.choice参数:

        choices = (
            (1,''),(2,''),(3,'其他')
        )
        gender = models.IntegerField(choices=choices)
        1.存: choices 里面 数字与中文的对应关系
        2.取: get_gender_display()
            注: 只要是choices字段 ,在获取数字对应的注释就用 get_choices字段名_display()
        3. 要是存了 choices 里面没有的数字不会报错,但取时展现的是数字
    2.MTV 与 MVC 框架
        mtv框架:
          m:models
          t:templates
          v:views
        mvc框架:
          m:models
          v:views
          c:controller  控制器(urls)
        注: django自称是 MTV框架 ,本质上 还是 MVC 框架
    3.ajax
    特点:异步提交 局部刷新 
    请求方式: GET  POST  
    补充: request.is_ajax():用来判断请求是否是ajax请求 小结:
    1.a标签中的href属性 GET请求 2.浏览器中输入的url GET请求 3.form表单 GET/POST都支持 4.ajax  GET/POST都支持 优点:ajax最大的优点是在不重新加载整个页面的情况下,与服务器交互数据并 实现局部更新网页内容

    小例子
        页面上有三个input框在前两个input框中输入数字点击按钮 发送ajax请求 不刷新页面的情况下第三个框中自动算出两数之和
                
    前端:
                    <input type="text" id="i1"> + <input type="text" id="i2"> = <input type="text" id="i3">
                    <button id="b1">求和</button>
                    
                    $('#b1').on('click',function () {
                        {#alert(123)#}
                        // 点击按钮 朝后端发送post请求
                        $.ajax({
                            url:'',  // 控制发送给谁 不写就是朝当前地址提交
                            type:'post',  // 发送方式是post请求
                            data:{'i1':$('#i1').val(),'i2':$('#i2').val()},  // 发送的数据
                            success:function (data) {  // data形参用来接收异步提交的结果
                                {#alert(data)#}
                                // 将后端计算好的结果 通过DOM操作 渲染到第三个input矿中
                                $('#i3').val(data)
                            }
                        })
                    })
                
                后端:
                def index(request):
                    #request.is_ajax() 用来判断当前请求方式是否是ajax请求
                    if request.is_ajax():
                        if request.method == 'POST':
                            # print(request.POST)
                            i1 = request.POST.get('i1')
                            i2 = request.POST.get('i2')
                            # 后端获取的前端数据 都是字符串格式
                            res = int(i1) + int(i2)
                            return HttpResponse(res)
    
    
    
     
    4.前后端传输数据编码格式
     编码格式:
        1.urlencoded
        2.formdata
        3.json
        
     form表单
        1.编码格式默认是urlencoded的,数据格式:name=jssd&pwd=234,dj后端会把
          urlencoded编码格式的数据自动解析并放入request.POST中;
        2.编码格式可以修改为formdata来传文件,django后端会把符合urlencoded编码格式的数据放入 request.POST中,
          会把符合formdata编码格式的数据放入 request.FILES中;
        注: 前后端传输数据时 数据格式 一定要与你的编码格式 一致
    
     ajax传数据:
        1.它默认的编码格式是urllencode,方法同 form 表单
        2.可以传 json 格式的数据,  后端会把数据原封不动的放入request.body 中,需要开发者手动 解析
      
    前端:
                        <input type="file" id="d1">
                        $('#b1').on('click',function () {
                            alert(123)
                            // 点击按钮 朝后端发送post请求
                            $.ajax({
                                url:'',  // 控制发送给谁 不写就是朝当前地址提交
                                type:'post',  // 发送方式是post请求
                                data:JSON.stringify({'username':'jason','password':123}),  // 发送的数据
                                contentType:'application/json',  // 告诉后端你这次的数据是json格式
    
                                success:function (data) {  // data形参用来接收异步提交的结果
                                    alert(data)
                                    // 将后端计算好的结果 通过DOM操作 渲染到第三个input矿中
                                    $('#i3').val(data)
                                }
    
                            })
                    后端:
                        import json
                        
                        def index(request):
                            if request.method == 'POST':
                                print(request.body)
                                # 后端 需要手动去request.body中获取json格式数据  自己处理
                                jason_str = request.body
                                s = jason_str.decode('utf-8')
                                ral_d = json.loads(s)
                                print(ral_d,type(ral_d))
                                return HttpResponse('OK')
                            return render(request,'index.html')
    
    
    
      
    
     ajax传文件:
        获取文件标签存储文件的方法
            1. 用jquery 找到 存储文件的input标签
            2. 把jq 转为 js
            3. 用js对象的方法 .files[0] 获取标签内部存储的文件对象
            4. processData与contentType的参数 一定要设置为 false
    前端:
                        <form action="" method="post" enctype="multipart/form-data">
                            username:<input type="text" name="name">
                            password:<input type="text" name="pwd">
                            info:<input type="file" name="myfile">
                            <input type="submit">
                        </form>
                        
                        $('#b1').on('click',function () {
                            // ajax传输文件 建议使用内置对象formdata
                            var formData = new FormData();  // 既可以传普通的键值对 也可以传文件
                            // 添加普通键值
                            formData.append('username','jason');
                            formData.append('password','123');
                            // 传文件
                            // 如何获取文件标签所存储的文件对象?  固定语法
                            // 1.先用jQery查找到存储文件的input标签
                            // 2.将jQuery对象转成原生js对象
                            // 3.利用原生js对象的方法 .files[0]获取到标签内部存储的文件对象
                            // 4.一定要指定两个参数都为false
                            formData.append('my_file',$('#d1')[0].files[0]);
                            $.ajax({
                                url:'',  // 控制发送给谁 不写就是朝当前地址提交
                                type:'post',  // 发送方式是post请求
                                data:formData, // 发送的数据
    
                                // ajax发送文件需要指定两个额外的参数
                                processData:false,  // 告诉前端不要处理数据
                                contentType:false,  // 不适用任何编码  因为formdata对象自身自带编码 django后端也能够识别formdata对象
    
                                success:function (data) {  // data形参用来接收异步提交的结果
                                    {#alert(data)#}
                                    // 将后端计算好的结果 通过DOM操作 渲染到第三个input矿中
                                    $('#i3').val(data)
                                }
    
                            })
                        })
                                
                    后端:
                        def index(request):
                            if request.method == 'POST':
                                print('request.POST',request.POST)
                                print('request.FILES',request.FILES)
                                return HttpResponse('OK')
                            return render(request,'index.html')        

    5.序列化组件(django自带,小型的):serializers
      

    from django.core import serializers  # django自带的一个小型的序列化工具
            def reg(request):
                user_l ist = models.User.objects.all()
                res = serializers.serialize('json',user_list)
                return render(request,'index.html',locals())
            
            [{
                    "model": "app01.user",
                    "pk": 1,
                    "fields": {
                        "username": "jason",
                        "age": 18,
                        "gender": 1
                    }
                }, {
                    "model": "app01.user",
                    "pk": 2,
                    "fields": {
                        "username": "tank",
                        "age": 24,
                        "gender": 3
                    }
                }, {
                    "model": "app01.user",
                    "pk": 3,
                    "fields": {
                        "username": "egon",
                        "age": 73,
                        "gender": 2
                    }
                }, {
                    "model": "app01.user",
                    "pk": 7,
                    "fields": {
                        "username": "kevin",
                        "age": 29,
                        "gender": 4
                    }
            }]
            
        

    6.sweetalert

     前端: 
     1     <body>
     2         <div class="container">
     3             <div class="row">
     4                 <div class="col-md-8 col-md-offset-2">
     5                     <h2 class="text-center">数据展示</h2>
     6                     <table class="table-striped table table-hover table-bordered">
     7                         <thead>
     8                             <tr>
     9                                 <th>序号</th>
    10                                 <th>主键</th>
    11                                 <th>用户名</th>
    12                                 <th>年龄</th>
    13                                 <th>性别</th>
    14                                 <th>操作</th>
    15                             </tr>
    16                         </thead>
    17                         <tbody>
    18                             {% for user in user_list %}
    19                                 <tr>
    20                                     <td>{{ forloop.counter }}</td>
    21                                     <td>{{ user.pk }}</td>
    22                                     <td>{{ user.username }}</td>
    23                                     <td>{{ user.age }}</td>
    24                                     <td>{{ user.get_gender_display }}</td>
    25                                     <td>
    26                                         <button class="btn btn-primary btn-sm">编辑</button>
    27                                         <button class="btn btn-danger btn-sm del" user_id="{{ user.pk }}">删除</button>
    28                                     </td>
    29                                 </tr>
    30                             {% endfor %}
    31                         </tbody>
    32                     </table>
    33                 </div>
    34             </div>
    35         </div>
    36         <script>
    37             $('.del').click(function () {
    38                 // 获取当前标签对象
    39                 var $btnEle = $(this);
    40 
    41                 swal({
    42                   title: "你确定要删吗?",
    43                   text: "你要是删了,你就准备跑路吧!",
    44                   type: "warning",
    45                   showCancelButton: true,
    46                   confirmButtonClass: "btn-danger",
    47                   confirmButtonText: "是的,老子就要删!",
    48                   cancelButtonText: "算了,算了!",
    49                   closeOnConfirm: false,
    50                   showLoaderOnConfirm: true
    51                 },
    52                 function(){
    53                     // 朝后端发送ajax请求
    54                     $.ajax({
    55                         url:'',
    56                         type:'post',
    57                         data:{'delete_id':$btnEle.attr('user_id')},
    58                         success:function (data) {  // 后端发字典过来 前端不需要你手动转 会自动帮你转换成js自定义对象
    59                             if (data.code == 100){
    60                                 {#window.location.href = '';  // 不写就是条到当前页面#}
    61                                 // 通过DOM操作 实时改变页面
    62                                 // 将被点击的删除按钮所在的那一行直接从DOM树中删掉
    63                                 $btnEle.parent().parent().remove();
    64                                 swal("删掉了!", "赶紧回去收拾行李吧,准备跑路!", "success");
    65                             }else{
    66                                 swal('发生了未知的错误','估计是有bug了','info')
    67                             }
    68                         }
    69                     });
    70 
    71                 });
    72             })
    73         </script>
    74 
    75      </body>
    View Code
    
    
     后端:
            def userlist(request):
                if request.is_ajax():
                    time.sleep(3)
                    """
                    一般情况下 针对ajax请求 后端通常都是返回一个字典
                    """
                    back_dic = {'code':100,'msg':''}
                    # 直接获取用户想删除的数据的id值
                    delete_id = request.POST.get('delete_id')
                    # 直接利用queryset方法 批量删除
                    models.User.objects.filter(pk=delete_id).delete()
                    # 要给前端ajax返回一个消息(字典)
                    back_dic['msg'] = '真的删除了!'
                    return JsonResponse(back_dic)
    
                user_list = models.User.objects.all()
                return render(request,'userlist.html',locals())

    7.自定义分页器

        知识点:
            1.bulk_creat() 批量插入数据 
                l = []
                for i in range(10000):
                    l.append(models.Book(title='第%s本书'%i))
                models.Book.objects.bulk_create(l)  # 批量插入数据,效率高
            2.creat() 逐条插入数据
                for i in range(1000):
                    models.Book.objects.create(title='第%s本书'%i)  # 效率极低
                    
        分页器的使用:
            后端代码:
                book_list = models.Book.objects.all()
                current_page = request.GET.get("page",1)
                all_count = book_list.count()
                page_obj = Pagination(current_page=current_page,all_count=all_count,per_page_num=10,pager_count=5)
                page_queryset = book_list[page_obj.start:page_obj.end]
            前端代码:
                {% for book in page_queryset %}
                <p>{{ book.title }}</p>
                {% endfor %}
                {{ page_obj.page_html|safe }}

    封装好的分页器:

    后端代码:
    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:  最多显示的页码个数
    
            用法:
            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)
    View Code
    
    
    前端代码:
                {% for book in page_queryset %}
                <p>{{ book.title }}</p>
                {% endfor %}
                {{ page_obj.page_html|safe }}
     
     
     
  • 相关阅读:
    AcWing 1135. 新年好 图论 枚举
    uva 10196 将军 模拟
    LeetCode 120. 三角形最小路径和 dp
    LeetCode 350. 两个数组的交集 II 哈希
    LeetCode 174. 地下城游戏 dp
    LeetCode 面试题 16.11.. 跳水板 模拟
    LeetCode 112. 路径总和 递归 树的遍历
    AcWing 1129. 热浪 spfa
    Thymeleaf Javascript 取值
    Thymeleaf Javascript 取值
  • 原文地址:https://www.cnblogs.com/wyf20190411-/p/11574148.html
Copyright © 2011-2022 走看看