首页 > 其他分享 >django 08 orm查询相关3

django 08 orm查询相关3

时间:2022-12-19 21:22:58浏览次数:47  
标签:models res 08 publish 查询 orm app01 print django

Q查询进阶

import os

def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoday07.settings')
    import django
    django.setup()
    from app01 import models
    # Q查询进阶操作
    """左边的查询条件依次写入 字段名,变量名"""
    from django.db.models import Q
    q_obj = Q()                       # 1.产生一个对象
    q_obj.connector = 'or'                       # 默认添加的多个查询条件是and关系,如此将其变为or关系
    q_obj.children.append(('pk',1))   # 2.添加查询条件
    q_obj.children.append(('price__gt',200))
    q_obj.children.append('title_contains','三') # 模糊查询
    res = models.Book.objects.filter(q_obj)      # 查询直接支持填写q对象
    print(res)
main()

ORM查询优化

# 1.orm查询默认都是惰性查询
   - orm的查询语句在用一个变量接收,但是不打印结果就不会执行该语句,叫惰性查询

# 2.orm查询自带分页处理
   - orm的查询语句在查询到结果数量很大时,就会自己分页以保证安全
   - orm查询后台的sql语句:
      SELECT `app01_book`.`id`, `app01_book`.`title`,
`app01_book`.`price`, `app01_book`.`publish_time`,
`app01_book`.`publish_id` FROM `app01_book` LIMIT 21; args=() """orm查询的sql语句自带limit分页""" # 3.only与defer
# orm查询优化
    '''拿所有数据对象'''
    res = models.Book.objects.all() # 结果是queryset [数据对象,数据对象]
    for obj in res:
        print(obj.title) # 三国演义
        print(obj.price) # 998.00

    '''拿到的数据对象是列表包字典的形式'''
    res = models.Book.objects.all().values('title','price')  # 结果是queryset [{},{}]
    for i in res:
        print(i)    # 结果是{'title': '三国演义', 'price': Decimal('998.00')}
        
    """结果是数据对象+含有指定字段对应的数据"""
    '''
    only查询,可以将括号中列举的字段封装到数据对象里面,
    使用括号里面的字段时不会再走数据库查询,
    括号里面没有的字段会走数据库查询,也可以获取到
    '''
# 1.only
    res = models.Book.objects.only('title','price')
    # print(res)  # queryset [数据对象,数据对象]
    for i in res:
        print(i.title) # 三国演义
        print(i.price) # 998.00
        print(i.publish_time)  # 2022-12-07
    '''
    defer查询与only相反,
    点击括号里存在的字段名走数据库查询,
    点击括号里不存在的不走数据库查询
    '''
# 2.defer
    res = models.Book.objects.defer('title', 'price')
    # print(res)  # queryset [数据对象,数据对象]
    for i in res:
        print(i.title)      # 三国演义
        print(i.price)       # 998.00
        print(i.publish_time)  # 2022-12-07
# 4.select_related与prefetch_related
'''select_related底层是连表操作,可以支持先连表后在进行查询封装'''
# 1.select_related
    res = models.Book.objects.select_related('authors')
    print(res)
          """
底层sql语句: SELECT `app01_book`.`id`, `app01_book`.`title`, `app01_book`.`price`,
`app01_book`.`publish_time`, `app01_book`.`publish_id`, `app01_publish`.`id`,
`app01_publish`.`name`,`app01_publish`.`address` FROM `app01_book`
INNER JOIN `app01_publish` ON (`app01_book`.`publish_id` = `app01_publish`.`id`)
LIMIT 21; args=() """
'''括号内仅仅支持一对一,一对多的字段''' res1 = models.Author.objects.select_related('author_detail') print(res1) res2 = models.Book.objects.select_related('publish')
# 底层先连表后查询封装 for obj in res2: print(obj.publish.name) # 结果:北京出版社 南京出版社 西京出版社
'''prefetch_related底层是子查询,会把一条sql当作另一个查询的条件,''' # 2.prefetch_related 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.相关重要概念
    脏读,幻读,不可重复度读,MVCC多版本控制
    https://www.cnblogs.com/juzijunjun/p/16936590.html

# 4.orm开启事务的方式
# django orm提供了至少三种开启事务的方式
# 方式一:全局开启(配置文件数据库相关添加键值对)
    当有请求过来时,Django会在调用视图方法前开启一个事务。如果请求却正确处理并正确返回了结果,
    Django就会提交该事务。否则,Django会回滚该事务
        在数据库配置文件处添加 : "ATOMIC_REQUESTS": True 
              DATABASES = {
                 'default': {
                     'ENGINE': 'django.db.backends.mysql',
                     'NAME': 'mxshop',
                     'HOST': '127.0.0.1',
                     'PORT': '3306',
                     'USER': 'root',
                     'PASSWORD': '123',
                     'OPTIONS': {
                          "init_command": "SET 
                          default_storage_engine='INNODB'",
                     #'init_command': "SET 
                          sql_mode='STRICT_TRANS_TABLES'", #配置开启严格sql模式
                     }
                     "ATOMIC_REQUESTS": True, #全局开启事务,绑定的是http请求响应整个过程
                     "AUTOCOMMIT":False,      #全局取消自动提交,慎用
                     },
                'other':{
               'ENGINE': 'django.db.backends.mysql', 
                      ......
                }                           # 还可以配置其他数据
# 方式2:局部使用(用视图函数装饰器) from django.db import transaction @transaction.atomic def view_func(request): # This code executes inside a transaction.
orm语句 return 返回值 # 方式3:局部使用(with上下文管理) from django.db import transaction def view_func(request): # This code executes in autocommit mode (Django's default). print('66666')
with transaction.atomic(): #保存点 # This code executes inside a transaction. orm语句
return 返回值



orm常用字段类型

# 1.AutoField:      主键自增
     primary_key=Ture   # 如果没有主键自增,则会创建一个主键id

# 2.IntegerField:   整型类型
     Big,Small也是整型
      
# 3.CharField:     字符类型
     max_length         # 表示字符长度
     verbose_name       # 别名
# 4.DecimalField 小数相关类型 max_digits # 数字允许的最大位数有几位
decimal_places # 小数点后面有几位
# 5.DateField: 日期字段 auto_now # 每次数据更新都会更新时间字段 auto_now_add # 数据只会在第一次创建时记录时间 # 6.DateTimeField: 日期时间字段 auto_now # 每次数据更新都会更新时间字段 auto_now_add # 数据只会在第一次创建时记录时间 # 7.BooleanField: 传入布尔值自动存0或1 # 8.TextField: 可以存储一大段文本 # 9.EmailField: 存储邮箱格式数据 # 10.FileField: 传入文件对象,自动保存到提前配置好的路径下并存储该路径信息 """ORM还支持用户自定义字段类型"""
# 定义阶段
class MyCharField(models.Model):
    def __init__(self,max_length,*args,**kwargs):
        self.max_length = max_length
        super().__init__(max_length=max_length,*args,**kwargs)

    def db_type(self, connection):
        return 'char(%s)' %self.max_length

# 使用阶段
class User(models.Model):
    name = models.CharField(max_length=32)
    info = MyCharField(max_length=64)

ORM常用字段参数

# 1.primary_key      主键
# 2.verbose_name     注释
# 3.max_length       字段长度
# 4.max_digits       小数总共有多少位
# 5.decimal_places   小数点后面的位数
# 6.auto_now         每次操作数据自动更新事件
# 7.auto_now_add     首次创建自动更新事件后续不自动更新
# 8.null             允许字段为空
# 9.default          字段默认值
# 10.unique          唯一值
# 11.db_index        给字段添加索引
# 12.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()
# 13.to              关联表
# 14.to_field        关联字段(不写默认关联数据主键)
# 15.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相似

 

标签:models,res,08,publish,查询,orm,app01,print,django
From: https://www.cnblogs.com/juzijunjun/p/16992690.html

相关文章