(补12月19)ORM查询优化、ORM事物操作、ORM常用字段参数、Ajax请求、Content-Type

时间:2023-01-30 22:11:33

ORM查询优化、ORM事物操作、ORM常用字段参数、Ajax请求、Content-Type

Q查询进阶操作

先产生一个对象
q_obj = Q()
修改默认对象
q_obj.connector = 'or'
添加查询条件,可以添加多个查询条件,第一个写一个字符串的字段名,第二个写元素具体的值
q_obj.children.append(('pk',1))
q_obj。children.append(('price__gt'))
添加好以后q对象支持直接用filter进行筛选
    res = models.Book.objects.filter(q)
    print(res)

ORM查询优化

1.ORM的查询默认都是惰性查询
2.ORM的查询自带分页处理
3.only与defer
	'''数据对象+含有指定字段对应的数据'''
    # res = models.Book.objects.only('title', 'price')
    # print(res)  # queryset [数据对象、数据对象]
    # for obj in res:
        # print(obj.title)  # 点击括号内填写的字段 不走SQL查询
        # print(obj.price)
        # print(obj.publish_time)  # 可以点击括号内没有的字段获取数据 但是会走SQL查询
        
    res = models.Book.objects.defer('title', 'price')
    # print(res)  # queryset [数据对象、数据对象]
    for obj in res:
        # print(obj.title)  # 点击括号内填写的字段 走SQL查询
        # print(obj.price)
        print(obj.publish_time)  # 点击括号内没有的字段获取数据 不走SQL查询
4.select_related与prefetch_related
	 # res = models.Book.objects.all()
    # for obj in res:
    #     print(obj.publish.name)  # 每次查询都需要走SQL
    # res = models.Book.objects.select_related('authors')  # 先连表后查询封装
    # res1 = models.Author.objects.select_related('author_detail')  # 括号内不支持多对多字段 其他两个都可以
    # print(res1)
    # for obj in res:
    #     print(obj.publish.name)  # 不再走SQL查询

    res = models.Book.objects.prefetch_related('publish')  # 子查询
    for obj in res:
        print(obj.publish.name)

ORM事物操作

1.事物的四大特性(ACID)
 原子性、一致性、隔离性、持久性
2.相关sql关键字
  开启事物:start transaction
  回滚:rollback
  确认:commit
  保存点:savepoint
3.django orm提供了至少三种开启事务的方式
	方式1:配置文件数据库相关添加键值对		全局有效
       "ATOMIC_REQUESTS": True每次请求所涉及到的orm操作同属于一个事务
	方式2:装饰器							局部有效
       from django.db import transaction
       @transaction.atomic
       def index():pass	
 	方式3:with上下文管理					局部有效
       from django.db import transaction
    	def reg():
    		with transaction.atomic():
             pass

ORM常用字段类型

1.AutoField(int自增序列)
	int自增序列,必须填入的参数primary_key=True,如果没有自增的序列,则会自动创建一个列名为id的列。
    
2.CharField(varchar)
	verbose_name:字段的注释
     max_length:字符长度
        
3.IntegerField(int) 
	
4.BigIntegerField(bigint) 

5.DecimalField(decimal)
	max_digits:总共的位数
    decimal_places:小数位
    
6.EmailField(varchar(254))

7.DateField(date)
	日期字段,日期格式  YYYY-MM-DD,相当于Python中的datetime.date()实例
    
8.DateTimeField(datetime)
	日期时间字段,格式 YYYY-MM-DD HH:MM:SS,相当于Python中的datetime.datetime()实例
     auto_now:每次修改数据的时候会自动更新当前 的时间
     auto_now_add:在创建数据的时候记录创建时间后续不会自动修改了
        
9.BoolField(field)(布尔值类型)
	该字段传布尔值(False/True) 数据库里面存0/1
    
10.TextField(Field)(文本类型)
	该字段可以用来存大段内容(文章、博客...)  没有字数限制
	后面的bbs作业 文章字段用的就是TextField

11.FileField(Field)(字符类型)
	upload_to = "/data"
	给该字段传一个文件对象,会自动将文件保存到/data目录下然后将文件路径保存到数据库中
	/data/a.txt
    
12.ForeignKey()()外键

13.OneToOneField()(一对一关系)

14.ManyToManyField()(多对多关系)


ORM还支持自定义字段

# 定义char类型

# 字段类内部都继承Field
class MyCharField(models.Field):
    # 字符类型都必须有max_length表示字符长度
    def __init__(self,max_length, *args, **kwargs):
        self.max_length = max_length
        # 调用父类的init方法
        super().__init__(max_length=max_length, *args, **kwargs)  # 一定要是关键字的形式传入

    def db_type(self, connection):
        # 返回真真正的数据类型及各种约束条件
        return 'char(%s)' % self.max_length

# 自定义字段使用
myfield = MyCharField(max_length=16,null=True)  # 可以为空

(补12月19)ORM查询优化、ORM事物操作、ORM常用字段参数、Ajax请求、Content-Type

ORM常用字段参数

primary_key 	主键
verbose_name	注释
max_length		字段长度
max_digits     小数总共多少位
decimal_places	小数点后面的位数
auto_now		每次操作数据自动更新事件
auto_now_add	首次创建自动更新事件后续不自动更新
null			允许字段为空
default			字段默认值
unique			唯一值
db_index		给字段添加索引
choices			当某个字段的可能性能够被列举完全的情况下使用
	性别、学历、工作状态、...
	class User(models.Model):
        name = models.CharField(max_length=32)
        info = MyCharField(max_length=64)
        # 提前列举好对应关系
        gender_choice = (
            (1, '男性'),
            (2, '女性'),
            (3, '其他'),
        )
        gender = models.IntegerField(choices=gender_choice,null=True)
    user_obj = User.objects.filter(pk=1).first()
    user_obj.gender 
    user_obj.get_gender_display()
    
to				关联表
to_field		关联字段(不写默认关联数据主键)
on_delete		当删除关联表中的数据时,当前表与其关联的行的行为。
    1、models.CASCADE
        级联操作,当主表中被连接的一条数据删除时,从表中所有与之关联的数据同时被删除
    2、models.SET_NULL
        当主表中的一行数据删除时,从表中所有与之关联的数据的相关字段设置为null,此时注意定义外键时,这个字段必须可以允许为空
    3、models.PROTECT
        当主表中的一行数据删除时,由于从表中相关字段是受保护的外键,所以都不允许删除
    4、models.SET_DEFAULT
        当主表中的一行数据删除时,从表中所有相关的数据的关联字段设置为默认值,此时注意定义外键时,这个外键字段应该有一个默认值
    5、models.SET()
        当主表中的一条数据删除时,从表中所有的关联数据字段设置为SET()中设置的值,与models.SET_DEFAULT相似,只不过此时从表中的相关字段不需要设置default参数
    6、models.DO_NOTHING
        什么都不做,一切都看数据库级别的约束,注数据库级别的默认约束为RESTRICT,这个约束与django中的models.PROTECT相似

Ajax

特点:异步提交,局部刷新
ajax不是一门新的技术并且有很多版本 我们目前学习的是jQuery版本(版本无所谓 本质一样就可以)
异步提交,局部刷新的效果如图所示:

(补12月19)ORM查询优化、ORM事物操作、ORM常用字段参数、Ajax请求、Content-Type

ajax的基本语法:
$.ajax({
    url:'' //后端的地址,三种填写方式
    type:'post'  //请求方式,默认为get
    data:{'v1':v1Val,'v2':v2Val}  //发送数据
    success:function(args){  //异步回调函数
        // 后端返回结果之后自动触发 args接收后端返回的数据
        $('#d3').val(args)
    }
})

Ajax的小案例

url:
urlpatterns = [
    path('admin/', admin.site.urls),

    path('ab_ajax/', views.ab_ajax_func)
]
views:
def ab_ajax_func(request):
    if request.method == 'POST':
        print(request.POST)
        v1 = request.POST.get('v1')
        v2 = request.POST.get('v2')
        res = int(v1) + int(v2)
        return HttpResponse(res)
    return render(request, 'abAjaxPage.html')
abAjaxPage.html:
<input type="text" >
<button >点我发送ajax请求</button>
<script>
    // 2.给按钮绑定点击事件
    $('#d2').blur(function () {
        // 1.先获取两个框里面的数据
        let v1Val = $('#d1').val();
        let v2Val = $('#d2').val();
        // 3.发送ajax请求
        $.ajax({
            url:'',  // 后端地址 三种填写方式 与form标签的action一致
            type:'post',  // 请求方式 默认也是get
            data:{'v1':v1Val, 'v2':v2Val},  // 发送的数据
            success:function (args) {  // 后端返回结果之后自动触发 args接收后端返回的数据
                $('#d3').val(args)
            }
        })
    })
</script>

(补12月19)ORM查询优化、ORM事物操作、ORM常用字段参数、Ajax请求、Content-Type

Content-Type

1.urlencoded
	ajax默认的编码格式、form表单默认也是
	数据格式  xxx=yyy&uuu=ooo&aaa=kkk
 	django后端会自动处理到request.POST中
    
2.formdata
	django后端针对普通的键值对还是处理到request.POST中 但是针对文件会处理到request.FILES中
	
    
3.application/json
	form表单不支持 ajax可以
	<script>
    $('#d1').click(function () {
        $.ajax({
            url:'',
            type:'post',
            data:JSON.stringify({'name':'jason','age':18}),  // 千万不要骗人家
            contentType:'application/json',
            success:function (args) {
                alert(args)
            }

        })
    })
</script>
	后端需要从request.body中获取并自己处理

(补12月19)ORM查询优化、ORM事物操作、ORM常用字段参数、Ajax请求、Content-Type

ajax携带文件数据

<script>
    $('#d3').click(function () {
        // 1.先产生一个FormData对象
        let myFormDataObj = new FormData();
        // 2.往该对象中添加普通数据
        myFormDataObj.append('name', 'jason');
        myFormDataObj.append('age', 18);
        // 3.往该对象中添加文件数据
        myFormDataObj.append('file', $('#d2')[0].files[0])
        // 4.发送ajax请求
        $.ajax({
            url:'',
            type:'post',
            data:myFormDataObj,

            // ajax发送文件固定的两个配置
            contentType:false,
            processData:false,
            success:function (args){
                alert(args)
            }

        })
    })
</script>