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 }}
     
     
     
  • 相关阅读:
    Spring ApplicationListener 理解
    Tomcat 的context.xml说明、Context标签讲解
    IntrospectorCleanupListener作用
    Dubbo 和 Spring Cloud微服务架构 比较及相关差异
    ZooKeeper原理 --------这可能是把ZooKeeper概念讲的最清楚的一篇文章
    Dubbo 入门
    makefile的调试器remake
    linux下的nmap工具能干什么?
    makefile中的patsubst函数有何作用?
    openwrt为何需要refresh新增的补丁?
  • 原文地址:https://www.cnblogs.com/wyf20190411-/p/11574148.html
Copyright © 2011-2022 走看看