• Django篇--->七


    Django查询

    聚合查询
            关键字:aggregate
    		from django.db.models import Max,Min,Count,Sum,Avg
    
    	分组查询
            关键字:annotate
            1.最简单的规律
                models后面点什么 就是按什么分组  
            
    	F与Q查询
            from django.db.modles import F,Q
            F  能够帮助你获取到表中字段所对应的数据
            # 书籍的库存数与卖出数
            models.Book.objects.filter(kucun__gt=F('maichu'))
            
            因为filter过滤的条件的都是and连接 
            modesls.Book.objects.filter(Q(title='python'),Q(price=666))
            modesls.Book.objects.filter(Q(title='python')|Q(price=666))
            modesls.Book.objects.filter(~Q(title='python')|Q(price=666))
            
            # Q进阶用法
            q = Q()
            q.connector = 'or'
            q.children.append(('title','python'))
            q.children.append(('title__icontains','python'))
            q.children.append(('price',666))
            models.Book.objects.filter(q)  # 默认还是and关系  
    	
    	django中如何开启事务
            from django.db import transaction
            try:
                with transaction.atomic():
                    # 事务操作
            except BaseException as e:
                print(e)  
    	
        
      
        
    	常见字段及参数
            AutoField()
            DateField()
            DateTimeField()
                auto_now
                auto_now_add
            TextField()
            EmailField()          varchar(...)
            BooleanField()        传布尔值  存0/1
            
             
    	
    	自定义char字段
            class MyCharField(models.Field):
                
                
                def db_type(self,connection):
                    return 'char(%s)'%self.max_length
                
    	
    	orm查询优化
            only
            defer
            
            
            select_related
            prefetch_related
            
    	图书管理系统
    		书籍的增删改查
    

    模型表的choice参数
    比如选择性别‘男女’,往数据库中填写的数字是0,1

    模型层

    class Userinfo(models.Model):
        username = models.CharField(max_length=32)
        password = models.IntegerField()
    
        # 定义 choice 参数
        choices = (
            (1, 'male'),
            (2, 'female'),
            (3, 'others')
        )
        gender = models.IntegerField(choices=choices)
    
        '''
        定义choice参数时,括号内放的对应关系是一个个元组,如果我存入的数字不在我模型层
        定义的choice参数内(注意:虽然存入的数字没有对应关系,但是是可以存的)
        '''
    

    视图层

    from app01 import models
    
        res = models.Userinfo.objects.filter(pk=1).first()
        ret = models.Userinfo.objects.filter(pk=4).first()
        print(res.username) #jason
        print(res.gender) # 1
        # 正确方式
        print(res.get_gender_display()) # male
    
        print(ret.username) # nick
        print(ret.gender)# 3
        # 正确方式
        print(ret.get_gender_display()) # others
        
        res = models.Userinfo.objects.filter(pk=5).first()
        print(res.get_gender_display()) # 4  数字4没有在choice参数内设置对应值,所以取出的											 任然是数字
        '''
        如上所示,针对choices字段,如果你想要获取数字对应的值,不能直接点字段取值
        固定的书写方式为:数据对象.get_字段名_display(),当需要取值的数字不在choice参数内所设置的对应关系,那么取值获取到的还是数字
        '''
    

    choice参数使用模版

    record_choices = (('checked', "已签到"),
                          ('vacate', "请假"),
                          ('late', "迟到"),
                          ('noshow', "缺勤"),
                          ('leave_early', "早退"),
                          )
            record = models.CharField("上课纪录", choices=record_choices, 												default="checked",) 
        
        
            
            
            score_choices = ((100, 'A+'),
                         (90, 'A'),
                         (85, 'B+'),
                         (80, 'B'),
                         (70, 'B-'),
                         (60, 'C+'),
                         (50, 'C'),
                         (40, 'C-'),
                         (0, ' D'),
                         (-1, 'N/A'),
                         (-100, 'COPY'),
                         (-1000, 'FAIL'),
                         )
            score = models.IntegerField("本节成绩", choices=score_choices, 												default=-1)
        
    

    MTV与MVC模型

    django号称是MTV框架,其实它还是MVC框架
    	MTV:
    		M: models
    		T: templates
            V: views
        MVC:
            M: modles
    		V: views
    		C: controller(路由匹配)
    

    Ajax(*****)

    什么是Ajax: AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)

    AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

    ​ 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;(等待期间不做任何事)

    ​ 异步交互:客户度发出一个请求后,不需要等待服务器响应结束,可直接发出第二个请求。(直接执行下一行代码)

    ​ 阻塞与非阻塞:表示的是程序的执行状态

    Ajax优点

    • AJAX使用JavaScript技术向服务器发送异步请求;
    • AJAX请求无须刷新整个页面;
    • 因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高;

    两个关键点:1.局部刷新:一个页面,不是整体刷新,而是页面的某个地方局部刷新
    2.异步提交

    基于jQuery实现的Ajax

    ajax基本语法

    //在 html script中使用
    $.ajax({
        url: '/index/',  //提交的数据路径,不写默认是当前路径
        type: 'post',   //标定ajax的请求方式
        data:{'name':'jason', 'age': 18},  //data后面跟的是你提交给后端的数据
        //success 为回调函数
        success:function(data){    //data是后端返回的数据
            alert(data)
        }
        
    })
    

    1.展示一个前端页面,页面上有三个输入框,前面两个框输入数字,点击按钮朝后端发送请求,页面在不刷新的情况下,完成数字的加法运算

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
    
    </head>
    <body>
    
    <input type="text" id="t1">+<input type="text" id="t2">=<input type="text" id="t3">
    <p>
        <button class='btn btn-primary' id="b1">计算</button>
    </p>
    
    <script>
        //绑定事件
        $('#b1').on('click',function(){
            //ajax写法
            $.ajax({
                url: '/index/',
                type: 'post', //设置发送方式是post请求
                //获取两个输入框的值
                data:{'t1':$('#t1').val(), 't2':$('#t2').val()},//data是提交给后端的数据
                //success回调函数
                success:function(data){   //data是后端返回的数据
                    $('#t3').val(data)
                }
            })
        })
    </script>
    </body>
    </html>
    

    views.py

    def index(request):
        if request.is_ajax():
            if request.method == 'POST':
                t1 = request.POST.get('t1') # 后端获取到前端的数据都是字符串形式
                t2 = request.POST.get('t2') # 后端获取到前端的数据都是字符串形式
                res = int(t1) + int(t2)  # 转换成 int类型
                return HttpResponse(res)
    
        return render(request, 'index.html')
    

    Ajax传 json 格式数据
    django后端针对json格式的数据,不会自动帮你解析,会原封不动的存放在 request.body 中,
    可以手动处理,获取数据

    json_bytes = request.body
    json.str = str(json_bytes,encoding='utf8')
    json_dict = json.loads(json.str)
    
    注意点:在前端html 中必须:
    	1.指定contentType参数
        	contentType: 'application/json'
        2.要将你发送的数据,确保是json格式的
        	data:JSON.stringify({'username': 'jason', 'password': '123'})
    

    js.html.py

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
      <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    
    </head>
    <body>
    <input type="text" name="name" id="d1">
    <input type="password" name="password" id="d2">
    <button id="d3">ajax提交json格式数据</button>
    </body>
    <script>
      $('#d3').click(function () {
          var pos_data = {'name':$('#d1').val(),'password':$('#d2').val()};  //获取input框数据
          //JSON.stringify相当于json.dumps(),转化成json格式的字符串
          var pos = JSON.stringify(pos_data);  //转换格式
    
          $.ajax({
              url:'',
              type:'post',
              data:pos,  //发送的数据
              contentType:'application/json',  //告诉后端你这次的数据是json格式
          dataType:'json',
              success:function (data) {
                  alert(data)
              }
    
          })
      })
    </script>
    </html>
    

    视图层

    def js(request):
        if request.method == 'POST':
            json_bytes = request.body
            # 后端 需要手动去request.body中获取json格式数据
            print(request.body) # b'{"name":"tank","password":"123"}'
            import json
            bytes_str = request.body.decode('utf-8')
            print(json.loads(bytes_str)) # {'name': 'tank', 'password': '123'}
        return render(request, 'js.html')
    

    form表单和Ajax传文件

    1.contentType前后端传输数据编码格式

    前后端传输数据编码格式

    • urlencoded
    • formdata
    • json

    2.form表单和ajax上传文件区别

    form表单

    1.默认使用的编码格式是urlencoded
    数据格式:name = jason&pwd=123
    django后端针对urlencoded编码格式的数据会自动解析并放在request.POST中供用户获取。
    
    2.可以修改formdata传文件
    django后端针对formdata编码格式的数据会自动解析并放在request.FILES中供用户获取。
    

    ​ 需要利用内置对象 Formdata,该对象即可以传普通键值,也可以传文件

    模型层

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    
    </head>
    <body>
    <form action="" enctype="multipart/form-data" method="post">
      <input type="text" name="username" id="t1">
      <input type="password" name="password" id="t2">
      <input type="file" name="myfile" id="myfile">
     <input type='submit' value = 'form表单上传文件'>    //form表单上传文件格式
      
    </form>
    <button id="b1">提交</button>   //ajax上传文件格式,触发下面的ajax
    <script>
    	//绑定提交按钮
        $('#b1').click(function() {
            //1.先生成一个Formdata对象
            var myFormdata = new FormData();
            //2.朝对象中添加普通键值
            myFormdata.append('username', $('#ti').val());  //既可以上传普通键值
            myFormdata.append('password', $('#t2').val());
            //3.朝对象中添加文件数据,分三步
                //1.先通过jQuery获取查到到标签
                //2.将jQuery对象转换成原生的js 对象
                //3.利用原生js对象的方法,直接获取文件内容
            myFormdata.append('myfile', $('#t3')[0].files[0]); //也可以上传文件
    
            $.ajax({
                url: '',
                type: 'post',
                data:myFormdata,  //直接丢对象
                // ajax传文件,一定要指定两个关键性的参数
                contentType: false,  //不用任何编码,因为Formdata对象自带编码,django能够识别该对象
                processData: false, //告诉浏览器不要处理我的数据,直接发就行
                success:function(data){    //后端返回给客户端数据
                    alert(data)
                }
            })
        })
    </script>
    </body>
    </html>
    

    视图层

    #forms表单上传文件
    def home(request):
        if request.method == 'GET':  //渲染页面
            return render(request,'home.html')
        #获取文件信息
        myfile = request.FILES.get('myfile')  //获取form表单上传的文件
        print(myfile)    //上传文件名
        return HttpResponse('ok')
    
    #ajax上传文件
    def upload(request):
        if request.is_ajax:
            if request.method == 'POST':
                print(request.POST)  # <QueryDict: {'username': ['undefined'], 'password': ['111']}>
                print(request.FILES) # <MultiValueDict: {'myfile': [<InMemoryUploadedFile: 考试内容.txt (text/plain)>]}>
                return HttpResponse('后端已收到')
        return render(request, 'upload.html')
    
    '''注意事项:ajax传文件需要注意的事项
    		1.利用formdata对象,能够简单的快速传输数据(普通键值 + 文件)
    		2.有几个参数
    				data:formdata  直接丢对象
    				contentType: false
    				processData: false
    
    '''
    '''1.form表单上传文件需要指定编码格式enctype = 'multipart/form-data'。ajax也需要设置一样的编码格式,然后需要创建一个Formdata对象
    获取file文件的内容都是通过request.FILES.get()'''
    

    总结:

    1.如果不是上传文件,form表单input的话,就直接传了,contentType默认是urlencoded编码方式
    2.如果是上传文件,ajax上传文件就是先创建一个Formdata对象,通过append,把key,value参数传进去。注意:form表单和ajax上传的文件都是通过request.FILES.get()获取。
    3.ajax提交json格式的数据,先创造出一个对象,把数据放在对象里面,然后转换成json格式的字符串,通过JSON.stringify(data),这里的contentType必须设置为'application/json',这样它的数据在视图中就能通过request.body获取到,是二进制格式,需要转换成字符串。
    4、在前端接收到后台json格式数据,可以在ajax那里写dataType:'json',它会自动转换成对象
    

    contentType前后端传输数据编码格式**

    contentType前后端传输数据编码格式
        
            form表单 默认的提交数据的编码格式是urlencoded
                urlencoded
                    username=admin&password=123这种就是符合urlencoded数据格式
                    
                    django后端针对username=admin&password=123的urlencoded数据格式会自动解析
                    将结果打包给request.POST 用户只需要从request.POST即可获取对应信息
                   
                formdata
                    django后端针对formdata格式类型数据 也会自动解析
                    但是不会方法request.POST中而是给你放到了request.FILES中
                
            ajax  ajax默认的提交数据的编码格式也是urlencoded
                username=jason&password=123
                
            总结:django后端针对不同的编码格式数据 会有不同的处理机制以及不同的获取该数据的方法
        
        """
        前后端在做数据交互的时候 一定一定要表明你所发的的数据到底是什么格式
        
        前段后交互 你不能骗人家
        你的数据时什么格式 你就应该准确无误告诉别人是什么格式   
    

    序列化组件

    视图层

    from app01 import models
    from django.core import serializers
    def ser(request):
        user_queryset = models.Userinfo.objects.all()
        #方式一# 自行封装成列表套字典
        # user_list = []  # 自行封装成列表套字典
        # for user_obj in user_queryset:
        #     user_list.append(
        #         {'username': user_obj.username,
        #          'password': user_obj.password,
        #          'gender': user_obj.get_gender_display}
        #     )
    
        # 方式二-用模块处理
        res = serializers.serialize('json', user_queryset)
        print(res)
    	return render(request, 'ser.html', locals())
    

    模板层

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    </head>
    <body>
    
    <p>{{ res }}</p> # 模块处理,直接将所有信息封装到一个个字典中,方式二
        #以下对应的是方式一
    {#<p>{{ user_list }}</p>   #列表里面套字典#}
    {#{% for foo in user_list %}#}
    {#    <p>{{ foo.username }}</p>#}
    {#    <p>{{ foo.password }}</p>#}
    {#    <p>{{ foo.gender }}</p>   # 字典取值#}
    
    {#{% endfor %}#}
    
    </body>
    </html>
    

    ajax + sweetalert

    模型层

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
        {% load static %}
        <link rel="stylesheet" href="{% static 'dist/sweetalert.css' %}">
        <script src="{% static 'dist/sweetalert.min.js' %}"></script>
        <style>
            div.sweet-alert h2 {
                padding-top: 10px;
            }
        </style>
    </head>
    <body>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <h2>数据展示</h2>
                <table class="table table-hover table-striped table-bordered">
                    <thead>
                        <tr>
                            <th>序号</th>
                            <th>用户名</th>
                            <th>密码</th>
                            <th>性别</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        {% for user_obj in user_queryset %}
                            <tr>
                                <td>{{ forloop.counter }}</td>
                                <td>{{ user_obj.username }}</td>
                                <td>{{ user_obj.password }}</td>
                                <td>{{ user_obj.get_gender_display }}</td>
                                <td>
                                    <a href="#" class="btn btn-primary btn-sm">编辑</a>
                                    <a href="#" class="btn btn-danger btn-sm cancel" delete_id="{{ user_obj.pk }}">删除</a>
                                </td>
                            </tr>
                        {% endfor %}
                    </tbody>
    
    
                </table>
            </div>
        </div>
    </div>
    
    
    <script>
        $('.cancel').click(function () {
            var $btn = $(this);
            swal({
              title: "你确定要删吗?",
              text: "你要是删了,你就准备好跑路吧!",
              type: "warning",
              showCancelButton: true,
              confirmButtonClass: "btn-danger",
              confirmButtonText: "对,老子就要删!",
              cancelButtonText: "算了,算了!",
              closeOnConfirm: false,
                showLoaderOnConfirm: true
            },
            function(){
                $.ajax({
                    url:'',
                    type:'post',
                    data:{'delete_id':$btn.attr('delete_id')},
                    success:function (data) {
                        if (data.code==1000){
                            swal(data.msg, "你可以回去收拾行李跑路了.", "success");
                            // 1.直接刷新页面
                            {#window.location.reload()#}
                            // 2.通过DOM操作 实时删除
                            $btn.parent().parent().remove()
                        }else{
                            swal("发生了未知错误!", "我也不知道哪里错了.", "info");
                        }
                    }
                });
    
            });
        })
    </script>
    
    
    </body>
    </html>
    

    视图层

    """
    当你是用ajax做前后端 交互的时候 
    你可以考虑返回给前端一个大字典
    """
    import time
    from django.http import JsonResponse
    def sweetajax(request):
        if request.method == 'POST':
            back_dic = {"code":1000,'msg':''}
            delete_id = request.POST.get('delete_id')
            models.Userinfo.objects.filter(pk=delete_id).delete()
            back_dic['msg'] = '后端传来的:真的被我删了'
            time.sleep(3)
            return JsonResponse(back_dic)
        user_queryset = models.Userinfo.objects.all()
        return render(request,'sa.html',locals())
    
  • 相关阅读:
    【重磅】FineUIPro基础版免费,是时候和ExtJS说再见了!
    【续】抓个Firefox的小辫子,jQuery表示不背这黑锅,Chrome,Edge,IE8-11继续围观中
    FineUICore已发布,跨平台速度快(现在可申请试用)!
    【原创】抓个Firefox的小辫子,围观群众有:Chrome、Edge、IE8-11
    快了快了,你的 MacBook Pro 和 FineUICore!
    [ASP.NET Core 2.0 前方速报]Core 2.0.3 已经支持引用第三方程序集了
    [译]ASP.NET Core 2.0 区域
    [译]ASP.NET Core 2.0 视图组件
    [译]ASP.NET Core 2.0 部分视图
    [译]ASP.NET Core 2.0 布局页面
  • 原文地址:https://www.cnblogs.com/chmily/p/11757036.html
Copyright © 2020-2023  润新知