day55总结

末鹿安然 提交于 2019-12-06 12:33:44

orm查询优化

惰性查询, 目的: 减少不必要的数据库操作, 降低数据库的压力

缓存数据库, redis, mongodb, 目的: 缓解主库压力, 相当于一个非常大的内存, 速度快同时也能做持久化

能少走一次数据库就少走一次

only与defer

only:

  1. only括号内放字段, 查询结果是一个列表套数据对象
  2. "对象.括号内的字段"不会再查询数据库, 直接获取属性值
  3. "对象.括号内没有的字段"会查询数据库获取结果
res = models.Book.objects.only('title')
print(res)  # <QuerySet [<Book: 红楼梦>, <Book: 西游记>, ...]>
for i in res:
    print(i.title)  # 查1次数据库
    print(i.price)  # 查5次数据库

defer:

  1. defer与only互为反操作
  2. "对象.括号内的字段"会查询数据库获取结果
  3. "对象.括号内没有的字段"不会再查询数据库, 直接获取属性值
res = models.Book.objects.only('title')
for i in res:
    print(i.title)  # 查5次数据库
    print(i.price)  # 查1次数据库
  1. select_related括号内只能放外键字段,
  2. 并且外键字段只能是多对一或者一对一, 不能是多对多,
  3. 内部是自动联表操作, 会将括号中的外键字段所关联的表与当前表自动拼接成一张表,
  4. 然后将表中的一条条数据封装成一个个对象, 使跨表查询也不需要重复走数据库,
  5. 括号中可以放多个外键字段, 会将全部外键字段关联的表与当前表拼成一张大表
res = models.Book.objects.all()
for i in res:
    print(i.publish)  # 查询外键信息时, 需查询5次数据库

res = models.Book.objects.select_related('publish')
for i in res:
    print(i.title)  # 查1次数据库
    print(i.publish)  # 查1次数据库
  1. 内部是子查询, 按步骤查询多张表, 然后将查询的结果封装到对象中, 给用户的感觉像是联表操作
res = models.Book.objects.prefetch_related('publish', 'authors')
for i in res:
    print(i.publish)  # 查3次数据库
    print(i.authors.all())  # 查3次数据库

小结

selected_related: 耗时在数据库层面的联表操作上

prefetch_related: 耗时在查询的次数上

当两张表特别大时, selected_related花费时间可能更多

MTV与MCV模型

django自称为MTV框架, 本质还是MVC

MTV:

  • M: models
  • T: templates
  • V: views

MVC:

  • M: models
  • V: views
  • C: controllar, 包含urls.py, 路由匹配

choices参数

性别, 学历等字段可能性都是能完全列举的,

存数字, 取的时候按照提前设定的对应关系取出真正的数据

migrations文件夹下必须要有一个__init__.py文件, 否则会报错: No changes detected

'''
class User(models.Model):
    ...
    gender_choice = (
        (1, '男'),
        (2, '女'),
        (3, '其他'),
    )
    gender = models.IntegerField(choices=gender_choice)


from app01 import models

user_obj1 = models.User.objects.get(pk=1)
user_obj2 = models.User.objects.get(pk=4)
print(user_obj1.get_gender_display())  # 男
print(user_obj2.get_gender_display())  # 4

如果存储的数字不在提前设定的对应关系中
    能够正常存储, 也能够正常获取
    
choices字段类型获取对应关系值的句式: get_字段名_display()
    弱限制, 没有对应关系时, 获取的结果为表中实际结果
    对应关系中的第一个参数不一定是数字, 也可以是字符串
'''

ajax简介

XML

xml也是一门标记语言, 应用场景:

  • 写配置文件
  • 写前端页面
  • 专门用来开发企业内部管理软件的框架: odoo
  • odoo框架内部功能实现全部依赖于python2, 薪资功能的实现最复杂

AJAX

最大的优点是在不重新加载整个页面的情况下, 可以与服务器交换数据并更新部分网页内容

同步交互: 客户端发出一个请求后, 需要等待服务器响应结束后, 才能发出第二个请求

异步交互: 客户端发出一个请求后, 无需等待服务器响应结束后, 就能发出第二个请求

'''
1. 页面上有三个input框
2. 前两个框输入数字, 并将输入的数字用post请求提交到后端, 最后一个框展示两数之和
3. 要求页面不刷新
'''
'''
1. 页面上有三个input框
2. 前两个框输入数字, 并将输入的数字用post请求提交到后端, 最后一个框展示两数之和
3. 要求页面不刷新


def ajax(request):
    # print(request.is_ajax())  # 判断当前请求是否是ajax请求
    # print(request.POST)  # ajax发送的post请求, 普通的键值对也在request.POST中

    if request.is_ajax():
        d1 = request.POST.get('d1')
        d2 = request.POST.get('d2')
        res = int(d1) + int(d2)
        return HttpResponse(res)  # 结果返回给异步回调函数, 一旦使用ajax请求, 数据只与回调函数交互

    return render(request, 'ajax.html')
    
    
<script>
    $('#d4').on(
        'click', function () {
            // 开启ajax语法句式:
            $.ajax({
                url: '',  // 控制数据的后端地址, 和form表单中的action用法一样
                type: 'post',  // 控制数据提交方式, 不写默认是get请求
                data: {'d1': $('#d1').val(), 'd2': $('#d2').val()},  // 提交的数据
                success: function (data) {  // data为异步提交数据后, 后端处理数据的返回结果
                    $('#d3').val(data)  // 回调函数处理返回结果
                }
            })

        }
    )
</script>
'''

前后端数据交互的编码格式

a标签的href参数: get请求

form表单: get/post请求, post请求无法发送json格式数据

ajax: get/post请求, post请求默认编码格式为urlencoded

get请求数据格式为单一格式: url?x=a&y=b

post请求的三种数据编码格式

  • urlencoded, multipart/formdata, application/json
  • 查看请求方式: f12-->Network-->Headers-->Request Headers-->Content-Type
  • 查看请求原数据: ...-->Form Data-->view source
  • django针对urlencoded数据, username=jason&password=123, 会自动解析并封装到request.POST中
  • django针对multipart/formdata数据, 在浏览器中无法查看, 但是会将满足urlencoded的数据解析到request.POST中, 将文件对象解析到request.FILES中
  • 发送json格式数据只能借助ajax
  • 在涉及前后端交互时, 要做到数据的格式与编码的格式一致
'''
<script>
    $('#d4').on(
        'click', function () {
            $.ajax({
                url: '', 
                type: 'post',  
                contentType: 'application/json',  // post请求发送json数据需要的参数及参数值
                data: JSON.stringify({'username': 'jason', 'password': '123'}),  // 前端数据使用JSON.stringify序列化为json格式
                success: function (data) {  
                    alert(data.username)  
                }
            })
        }
    )
</script>


def ajax(request):
    from django.http import JsonResponse
    import json

    if request.is_ajax():
        json_bin = request.body  # 获取json格式二进制数据
        json_str = json_bin.decode('utf8')  # 解码
        user_dic = json.loads(json_str)  # 反序列化
        return JsonResponse(user_dic)  # JsonResponse会自动将后端的字典转换成前端的object类型数据

    return render(request, 'ajax.html')
'''

ajax发送文件格式数据

Ajax传文件需要借助js中的内置对象

js实例化对象的关键字: new

该对象既可以携带文件数据, 也支持普通的键值对

'''
<script>
    $('#d1').on(
        'click',
        function () {
            var myFormData = new FormData();  // 实例化得到myFormData对象
            myFormData.append('username', 'jason');  // 添加普通键值数据
            myFormData.append('myfile', $('#d2')[0].files[0]);  // 获取input框中文件对象, 并添加到myFileData对象中
            $.ajax({
                ...,
                data: myFormData,
                contentType: false,  // 不使用myFormData对象内部自带的编码, 类似于json.dumps自动转码中文
                processData: false,  // 设置浏览器不处理发送的数据
                ...
            })
        }
    )
</script>


def ajax(request):
    if request.is_ajax():
        print(request.POST)  # <QueryDict: {'username': ['jason']}>
        print(request.FILES)  # <MultiValueDict: {'myfile': [<...: 20天背完四级核心词汇.pdf ...>]}>
    ...
'''

django内置的序列化模块

drf: django restframework

序列化的目的: 将数据整合成一个大字典的形式, 方便前后端分离之后数据的交互

def serialize(request):
    from django.core import serializers

    user_queryset = models.User.objects.all()

    res = serializers.serialize('json', user_queryset)  # json为序列化的数据格式

    return HttpResponse(res)
    # [{"model": "app01.user", "pk": 1, "fields": {"username": "jason", "password": 123, "gender": 1}}, ...]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!