Django-model进阶

it2023-09-21  63

文章目录

一 原生sql的使用二 defer与only三 事务(三种粒度)

一 原生sql的使用

# 1) 原生sql(有些sql用orm写不出来) # 2) 两种方案 # 第一种:用的比较少 from django.db import connection cursor = connection.cursor() cursor.execute("""SELECT * from app01_book where id = %s""", [1]) # 默认结果显示元组,若要显示字典的话,需要自定义设置,django未直接提供相关方法 row = cursor.fetchone() print(row) # (1, '西游记', Decimal('21.00'), datetime.datetime(2020, 10, 14, 20, 34, 25, 995754), 1, 99, 200) row = cursor.fetchall() print(row) # () # 第二种,用的多 # 1) 查找 id 大于3的书 books = models.Book.objects.raw('select * from app01_book where id >3') print(books) # <RawQuerySet: select * from app01_book where id >3> for book in books: print(book.name) # Python从入门到入狱 三体 # 2) 查找 所有 出版社信息 books = models.Book.objects.raw('select * from app01_publish') for book in books: # print(books.__dict__) print(book.name, end='<|-|>') print(book.addr, end='<|-|>') print(book.email, end='<|-|>') print(book.price) """ 北京出版社<|-|>北京<|-|>bj@qq.com<|-|>21.00 沙河出版社<|-|>北京<|-|>sh@qq.com<|-|>22.22 三体出版社<|-|>三体星<|-|>st@qq.com<|-|>66.66 """ # 3) authors = models.Author.objects.raw('SELECT app01_author.id,app01_author. NAME,app01_authordetail.gender FROM app01_author JOIN app01_authordetail ON app01_author.author_detail_id = app01_authordetail.id WHERE app01_authordetail.gender = 0') for author in authors: print(author.name) print(author.__dict__) """ 刘老牛 {'_state': <django.db.models.base.ModelState object at 0x000002035ED9AD00>, 'id': 1, 'NAME': '刘老牛', 'gender': 0, 'name': '刘老牛'} 小矮根 {'_state': <django.db.models.base.ModelState object at 0x000002035ED9ADC0>, 'id': 2, 'NAME': '小矮根', 'gender': 0, 'name': '小矮根'} 萧鼎 {'_state': <django.db.models.base.ModelState object at 0x000002035ED9AD00>, 'id': 3, 'NAME': '萧鼎', 'gender': 0, 'name': '萧鼎'} 刘慈欣 {'_state': <django.db.models.base.ModelState object at 0x000002035ED9AE20>, 'id': 4, 'NAME': '刘慈欣', 'gender': 0, 'name': '刘慈欣'} """

二 defer与only

# 由于使用了values()之后,可以取出想要的字段的数据,但是一个字典数组,我们仍然想要数据是一个对象,因此使用defer和only。 1) defer('id','name'): 取出对象,字段除了id和name都有 2) only('id','name'): 取的对象,只有id和name 3) 注意:如果点,依然能点出其它列,但是不要点了,因为取没有的列,会再次查询数据库 # #---->>>> defer和only(查询优化相关) books = models.Book.objects.all().only('name') print(books[0].name) print(books[0].price) # 可以查出来,但是会造成效率问题,多查询了一次才查出来的 books = models.Book.objects.all().only('name') print(books[0].__dict__) books = models.Book.objects.all().defer('name', 'price') print(books[0].__dict__) """ (0.000) SELECT `app01_book`.`id`, `app01_book`.`name` FROM `app01_book` LIMIT 1; args=() (0.000) SELECT `app01_book`.`id`, `app01_book`.`publish_date`, `app01_book`.`publish_id`, `app01_book`.`read_num`, `app01_book`.`commit_num` FROM `app01_book` LIMIT 1; args=() {'_state': <django.db.models.base.ModelState object at 0x0000026ECE849F40>, 'id': 1, 'name': '西游记'} {'_state': <django.db.models.base.ModelState object at 0x0000026ECE871340>, 'id': 1, 'publish_date': datetime.datetime(2020, 10, 14, 20, 34, 25, 995754), 'publish_id': 1, 'read_num': 200, 'commit_num': 99} """

三 事务(三种粒度)

# djanog orm中使用事务:原子性操作,要么都成功,要么都失败 # #---->>>> 事务:ACID,事务的隔离级别 # 示例:新增一个作者详情,新增一个作者 # 1 局部使用 from django.db import transaction with transaction.atomic(): # 都在事务中,要么都成功,要么都失败 author_detail = models.AuthorDetail.objects.create(addr='xxx', phone='123', sex=1) # raise Exception('抛了异常') author = models.Author.objects.create(name='llqz', age=19, author_detail=author_detail) # 2 视图函数装饰器,这一个视图函数都在一个事务中 @transaction.atomic def index(request): return HttpResponse('ok') # 3 整个http请求,在事务中,在setting.py中配置 ''' DATABASES = { 'default': { ... 'PORT': 3306, 'ATOMIC_REQUEST': True, } } 'ATOMIC_REQUEST': True, 设置为True统一个http请求对应的所有sql都放在一个事务中执行(要么所有都成功,要么所有都失败)。 '''
最新回复(0)