Django:ORM单表操作和多表操作、锁和事务
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- ORM简介
- ORM中的对象关系映射
- ORM的实际使用
- 执行数据库同步指令,在项目根目录下面执行
- 查看FIeld和mysql中的字段关系对比
- django配置连接msyql
- ORM 单表操作(增)
- ORM 单表操作(删)
- ORM 单表操作(改)
- 关于时间类型数据的小知识点
- ORM 单表操作(查)(重要)
- filter基于双下划线的模糊查询
- ORM 多表关系及操作
- ORM 表关系设计
- ORM 多表操作(增)
- ORM 多表操作(删)
- ORM多表操作(改)
- ORM多表操作(查)
- 正向查询和反向查询
- 一对一
- 一对多
- 多对多
- 基于双下划线的跨表查询
- 聚合查询
- 分组查询
- F查询
- Q查询
- 创建字段的一些参数讲解
- ORM执行原生sql语句(了解)
- raw()管理器方法用于原始的SQL查询
- connection模块 执行自定义SQL
- ORM中的锁和事务
- ORM中的锁
- ORM中的事务
ORM简介
MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动
ORM是“对象-关系-映射”的简称。(Object Relational Mapping,简称ORM)(将来会学一个sqlalchemy,是和他很像的,但是django的orm没有独立出来让别人去使用,虽然功能比sqlalchemy更强大,但是别人用不了)
类对象—>sql—>pymysql—>mysql服务端—>磁盘,orm其实就是将类对象的语法翻译成sql语句的一个引擎,明白orm是什么了,剩下的就是怎么使用orm,怎么来写类对象关系语句。
ORM中的对象关系映射
ORM的实际使用
首先,我们在django项目的app01/models.py中写入如下内容
class Book(models.Model):# 如果没有指定主键字段,默认orm会给这个表添加一个名称为id的主键自增字段# 如果制定了,以指定的为准,那么orm不在创建那个id字段了# AutoField类型为int并且自增加一id = models.AutoField(primary_key=True)# CharField类型为对应mysql中的varchartitle = models.CharField(max_length=32) # 书籍名称# DecimalField浮点类型 max_digits控制整数 decimal_places控制小数price = models.DecimalField(max_digits=5,decimal_places=2) # 价格# DateField日期类型pub_date = models.DateField() # 出版日期publish = models.CharField(max_length=32) # 出版社名称.Book生成的表名称为 应用名称_模型类名小写
执行数据库同步指令,在项目根目录下面执行
python manage.py makemigraitons
python manage.py migrate
指令执行的流程
查看FIeld和mysql中的字段关系对比
C:\ProgramData\Anaconda3\Lib\site-packages\django\db\backends\mysql\base.py
_data_types = {'AutoField': 'integer AUTO_INCREMENT','BigAutoField': 'bigint AUTO_INCREMENT','BinaryField': 'longblob','BooleanField': 'bool','CharField': 'varchar(%(max_length)s)','CommaSeparatedIntegerField': 'varchar(%(max_length)s)','DateField': 'date','DateTimeField': 'datetime','DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)','DurationField': 'bigint','FileField': 'varchar(%(max_length)s)','FilePathField': 'varchar(%(max_length)s)','FloatField': 'double precision','IntegerField': 'integer','BigIntegerField': 'bigint','IPAddressField': 'char(15)','GenericIPAddressField': 'char(39)','NullBooleanField': 'bool','OneToOneField': 'integer','PositiveIntegerField': 'integer UNSIGNED','PositiveSmallIntegerField': 'smallint UNSIGNED','SlugField': 'varchar(%(max_length)s)','SmallIntegerField': 'smallint','TextField': 'longtext','TimeField': 'time','UUIDField': 'char(32)',}
django配置连接msyql
在mysql中创建数据库
create database orm01 charset=utf8mb4;
settings.py配置文件中写上如下内容
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'orm01','HOST':'127.0.0.1','PORT':3306,'USER':'root','PASSWORD':'', #有密码的填密码}
}
在pyCharm中安装pymysql
pip install pymsyql
在项目主目录下的__init__.py
文件中写上如下内容
import pymysqlpymysql.install_as_MySQLdb()
** 注意:前提是需要安装pymysql : pip install pymysql**
执行数据库同步指令
只要换了新的数据库,migrate会重新执行migrations文件
python manage.py migrate
ORM 单表操作(增)
from django.shortcuts import render,HttpResponse
import datetime# Create your views here.
from app01 import models'''方式1'''obj = models.Book( # obj就是一个普通的类对象title='西游记',price=2.8,# pub_date='2000-08-12', # 可以直接写固定时间,也可以写datetime当前时间pub_date=datetime.datetime.now(), #时间日期类型publish='人民出版社',)obj.save() # 注意:必须要写save选项'''方式2'''obj = models.Book.objects.create( # obj是当前创建的新的记录对象title='红楼梦',price=9.9,# pub_date='2000-08-12', #这样的格式字符串pub_date=datetime.datetime.now(), # 时间日期类型publish='人民出版社',)print(obj.title) #通过模型类对象,直接获取属性对应的值print(obj.price)'''批量添加'''obj_list = [] # 创建一个空列表,用来存放类对象for i in range(1,4): # 创建4个类对象,每个对象都有4个字段obj = models.Book(title='水浒传' + str(i),price=i,pub_date=f'2000-08-1{i}',publish='夕阳红出版社',)obj_list.append(obj) # 将类对象添加到列表中models.Book.objects.bulk_create(obj_list) # bulk_create 批量添加
ORM 单表操作(删)
models.Book.objects.filter(id=3).delete() queryset类型数据可以调用delete方法删除查询结果数据
models.Book.objects.get(id=4).delete() 模型类对象也可以调用delete方法删除数据
ORM 单表操作(改)
'''方式1 通过queryset类型数据修改'''
'''注意:模型类对象不能调用update方法,会报错'''
models.Book.objects.filter(id=4).update(title='西游记',price=4,)
'''方式2 通过模型类对象来修改'''
obj = models.Book.objects.get(id=6)
obj.price = 18 # 找到model对象,使用model对象.属性修改值
obj.save()obj.update() # 注意:模型类对象不能直接使用update方法
关于时间类型数据的小知识点
在创建表时DatetimeField、DateField、TimeField这个三个时间字段,都可以设置如下属性
(7)auto_now_add配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。(8)auto_now配置上auto_now=True,每次更新数据记录的时候会更新该字段,标识这条记录最后一次的修改时间。
'''models.py文件'''
'''auto_now=True和auto_now_add是互斥的不能同时给字段加约束'''
pub_date = models.DateField(auto_now_add=True)
pub_date = models.DateField(auto_now=True)
还需要设置
'''
django默认用的utc时间来操作时间数据,如果需要改为本地时区来存储时间,那么需要修改django的配置文件在settings.py文件中修改如下内容
'''
# USE_TZ = True
USE_TZ = False
示例:
models.userinfo.objects.filter(id=1).update( #update不能触发自动更新时间的auto_now参数的作用,# # 如果用update方法来更新记录,并保存更新记录的时间,需要我们手动给该字段传入当前时间name='xxoo',b1=datetime.datetime.now())# 这种save方式能够触发auto_now参数自动更新修改时间的动作ret = models.userinfo.objects.get(id=2)ret.name='xxoo2'ret.save()
ORM 单表操作(查)(重要)
'''注意:queryset 类似于列表 需要在models.py文件中加上def __str__魔术方法来查看
def __str__(self):self.title
'''
'''all() 获取表中所有数据,结果为queryset类型'''
ret = models.Book.objects.all()
print(ret)
print(ret[0]) # 因为是列表类型,所以可以用索引取值'''filter() 获取部分数据,结果为queryset类型'''
ret = models.Book.objects.filter(title='西游记')
ret = models.Book.objects.filter(id=1,title='三国演义') # 多条件查询,条件之间是且的关系(and)
ret = models.Book.objects.filter(id=100) # 查不到数据,不会报错,返回空的queryset类型数据
print(ret)'''get() 获取单条数据,结果是model对象'''
ret = models.Book.objects.get(title='西游记')
print(ret)
'''关于get需要注意的点'''
# 1. get() 获取有且只能有一条
# 2.找不到会报错:Book matching query does not exist.
# 3.结果超过1条也报错: get() returned more than one Book -- it returned 3!'''exclude(**kwargs)排除'''
exclude(**kwargs): '''排除的意思,它包含了与所给筛选条件不匹配的对象,返回值是queryset类型'''
models.Book.objects.exclude(id=6),# 返回id不等于6的所有的对象,
models.Book.objects.all().exclude(id=6) # 在queryset基础上也调用exclude'''order_by(*field) 排序 queryset类型的数据来调用,对查询结果排序,默认是按照id来升序排列的,返回值还是queryset类型'''
models.Book.objects.all().order_by('price','id')
'''注意点'''
# 1.直接写price,默认是按照price升序排列,
# 2.按照字段降序排列,就写个负号就行了:order_by('-price'),
# 3.order_by('price','id')是多条件排序,按照price进行升序,price相同的数据,按照id进行升序'''reverse() 对查询结果反向排序 queryset类型的数据来调用,对查询结果反向排序,返回值还是queryset类型,在排序基础上才能使用'''
models.Book.objects.all().order_by('-id').reverse() # 注意:要在order_by 基础上使用
models.Book.objects.all().order_by('id').reverse()'''count() 计数 queryset类型的数据来调用,返回数据库中匹配查询(QuerySet)的对象数量'''
models.Book.objects.all().count()'''first() queryset类型的数据来调用,返回第一条记录'''
'''Book.objects.all()[0] = Book.objects.all().first() 得到的都是model对象,不是queryset'''
models.Book.objects.all().first()'''last() queryset类型的数据来调用,返回最后一条记录'''
# 注意:在ORM中不能使用负数索引
'''得到的都是model对象,不是queryset'''
ret = models.Book.objects.all()[-1] # 报错,不支持负数索引:Negative indexing is not supported.'''exists() 判断查询结果是有数据'''
'''queryset类型的数据来调用,如果QuerySet包含数据,就返回True,否则返回False'''
obj_list = models.Book.objects.all().exists() #判断是否有数据的效率高,只找一条记录'''values(*field) 可以获取指定字段数据 用的比较多,queryset类型的数据来调用,返回一个QuerySet'''
ret = models.Book.objects.values('title','price')
# 获取所有记录的某些字段数据,结果为querset类型,里面的元素是字典类型数据,属性名称为键,对应记录的字段数据为值
'''还可以通过queryset类型数据来调用'''
ret = models.Book.objects.all().values('title','price')'''values_list(*field) '''
'''它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列'''
ret = models.Book.objects.all().values_list('title','price')
ret = models.Book.objects.values_list('title','price')'''distinct() 'values和values_list得到的queryset类型的数据来调用,从返回结果中剔除重复记录 '''
# 一般配合values和values_list来使用
obj_list = models.Book.objects.all().values_list('price').distinct()
obj_list = models.Book.objects.values('price').distinct()
filter基于双下划线的模糊查询
# 1.按日期查询
ret = models.Book.objects.filter(pub_date__year='2000', pub_date__month='8',pub_date__day='12')# 2.以..开头/结尾
ret = models.Book.objects.filter(title__startswith='少妇') # 以..开头(区分大小写)
ret = models.Book.objects.filter(title__istartswith='py') # 以..开头(不区分大小写)
ret = models.Book.objects.filter(title__endswith='2') # 以..结尾(区分大小写)# 3.包含
ret = models.Book.objects.filter(title__icontains='th') # title值中包含python的(区分大小写)
ret = models.Book.objects.filter(title__contains='th') # title值中包含python的(不区分大小写)# 4.数字等于.../数字在某个范围内
ret = models.Book.objects.filter(price__in=[3,4]) # 等于3或者等于4 -- 3 or4
ret = models.Book.objects.filter(price__range=[1,3]) # 在1-3之间 between 1 and 3# 5.年份写纯数字和字符串数字都可以
ret = models.Book.objects.filter(pub_date__year=2018)
ret = models.Book.objects.filter(pub_date__year='2018') # 6.大于/大于等于/小于/小于等于
ret = models.Book.objects.filter(price__gt=3) # 价格大于3的
ret = models.Book.objects.filter(price__gte=3) # 价格大于等于3的
ret = models.Book.objects.filter(price__lt=3) # 价格小于3的
ret = models.Book.objects.filter(price__lte=3) # 价格小于等于3的
ORM 多表关系及操作
ORM 表关系设计
from django.db import models# 作者表
class Author(models.Model): # 比较常用的信息放到这个表里面name=models.CharField( max_length=32)age=models.IntegerField() #int# 与AuthorDetail建立一对一的关系,一对一的这个关系字段写在两个表的任意一个表里面都可以# django2.x版本必须手动指定on_delete=models.CASCADE级联模式(级联模式是指本表有改动所关联的表字段也会有改动)# db_constraint=False取消foreign key的强制约束效果,还可以继续使用orm的提供的属性或者方法来操作关系记录ad = models.OneToOneField(to="AuthorDetail", to_field='id', on_delete=models.CASCADE)# au = models.OneToOneField("AuthorDetail", db_constraint=False)# 作者详细信息表
class AuthorDetail(models.Model): # 不常用的放到这个表里面birthday=models.DateField()telephone=models.CharField(max_length=11)addr=models.CharField(max_length=64)# 出版社表
class Publish(models.Model):name=models.CharField( max_length=32)city=models.CharField( max_length=32)# 书籍表
class Book(models.Model):title = models.CharField( max_length=32)publishDate=models.DateField()price=models.DecimalField(max_digits=5,decimal_places=2)# publish=models.ForeignKey(to="Publish",to_field="id",on_delete=models.CASCADE)publish=models.ForeignKey(to="Publish") #默认级联删除,默认关联的是另外一张表的id字段authors=models.ManyToManyField(to='Author',) #自动创建第三张表,id author_id book_id,不会作为本表的字段出现
ORM 多表操作(增)
# 一对一# 1.用create增# 先创建作者详细记录,因为作者id字段和作者详细信息表的id字段做了关联,在添加作者时会找不到这个作者models.AuthorDetail.objects.create(birthday='2018-01-01',telephone='13800000000',addr='北京')ad_obj = models.AuthorDetail.objects.get(id=1) # 创建一对一的关联model对象,先找到作者详细信息表的idmodels.Author.objects.create(name='张三',age=38,# ad_id = ad_obj.id, # 方法一:如果用的是属性名称_id,那么值为关联记录的id值ad = ad_obj, # 方法二:如果写属性名称来添加关系数据,那么值为关联记录的模型类对象)# 一对多'''出版社和书是一对多的关系;一个出版社可以出版多本书'''pub_obj = models.Publish.objects.get(id=1)models.Book.objects.create(title='白洁2',price=10,publishDate='1980-07-07',# publishs=pub_obj, #如果写属性名称来添加关系数据,那么值为关联记录的模型类对象publishs_id=2, #如果用的是属性名称_id,那么值为关联记录的id值)# 多对多
'''书和作者是多对多的关系;一本书可以有多个作者,一个作者也可以写很多本书'''obj = models.Book.objects.filter(id=1).first()# 方法一:通过get(id=?)获取对象a1 = models.Author.objects.get(id=1)a2 = models.Author.objects.get(id=2)obj.authors.add(a1,a2)# 方法二:add中直接写idobj.authors.add(1,2)
ORM 多表操作(删)
# 一对一和一对多删除'''一对一和一对多 ,基本和单表一样(级联删除)'''models.Author.objects.get(id=1).delete()models.AuthorDetail.objects.get(id=2).delete()models.Book.objects.get(id=1).delete()# 多对多删除ret = models.Book.objects.get(id=2)ret.authors.clear() # 清空该书籍对应的第三张表中的记录(全部删除)ret.authors.remove(3,4) #指定删除该书和哪些作者的关系 (指定删除)
ORM多表操作(改)
# 一对一修改和一对多修改
models.Author.objects.filter(name='张三').update(name='李四',age=50,# ad=models.AuthorDetail.objects.get(id=1), 两种方式都可以ad_id=1,
)
# 多对多修改
obj = models.Book.objects.get(id=2)
obj.authors.set(['3',])
'''多对多修改使用set方法 注意:set的值是字符串,set的原理是clear+add(先清空在添加)'''
ORM多表操作(查)
正向查询和反向查询
正向查询: A表关联了B表,关联属性在A表,那么通过A表数据查询B表中数据时,叫做正向查询
正向查询语法: 正向查询使用对象.关联属性名称
反向查询: 反之,叫做反向查询码
反向查询语法: 反向查询使用对象.关联模型类名小写
一对一
'''一对一:正向查询'''
# 查看张三作者的家庭住址# 1.sql语句查询
select app01_authordetail.addr from app01_author inner join app01_authordetail on app01_author.ad_id app01_atuhordetail.id where app01_author.name='张三'
# 2.基于对象的跨表查询
obj = models.Author.objects.get(name='张三')
print(obj.ad.addr) '''一对一:反向查询'''
# 查询北京的作者名称
obj = models.AuthorDetail.objects.get(addr='北京')
print(obj.author.name) # 反向查询:对象.表名小写.属性
一对多
'''一对多:正向查询'''
# 查询西游记这本书的出版社
obj = models.Book.objects.get(title='西游记')
print(obj.publishs.name)'''一对多:反向查询'''
'''一对多查询,给一查多,结果有多个:要使用对象.表名_set.all()'''
# 查询马哥出版社出版的书籍有哪些
ret = models.Publish.objects.get(name='马哥出版社')
books = ret.book_set.all() # <QuerySet [<Book: Book object>, <Book: Book object>]>
print(books.values('title')) # all()查询的是queryset对象,想得到里面的具体内容,要用values(字段)
多对多
'''多对多:正向查询'''
# 查询西游记是谁写的
# 1.sql查询
select app01_author.name from app01_book inner join app01_book_authors on app01_book.id =
app01_book_authors.book_id inner join app01_author on app01_author.id = app01_book_authors.author_id# 2.正向查询
obj = models.Book.objects.get(title='西游记')
print(obj.authors.all().values('name'))'''多对多:反向查询'''
# 查询张三写了哪些书
obj = models.Author.objects.get(name='张三')
print(obj.book_set.all().values('title'))
基于双下划线的跨表查询
'''正向查询靠属性, 反向查询靠表名小写'''
# 一对一
# 查看张三作者的家庭住址
'''正向写法'''
ret = models.Author.objects.filter(name='张三').values('ad__addr')
'''反向写法'''
ret = models.AuthorDetail.objects.filter(author__name='张三').values('addr')
print(ret) # <QuerySet [{'addr': '北京'}]># 一对多
# 查询西游记这本书的出版社
'''正向写法'''
ret = models.Book.objects.filter(title='西游记').values('publishs__name')
print(ret) # <QuerySet [{'publishs__name': '小马哥出版社'}]>
'''反向写法'''
ret = models.Publish.objects.filter(book__title='西游记').values('name')
print(ret) # <QuerySet [{'name': '小马哥出版社'}]># 多对多
# 查询水浒传是谁写的
'''正向写法'''
ret = models.Book.objects.filter(title='水浒传').values('authors__name')
print(ret)
'''反向写法'''
ret = models.Author.objects.filter(book__title='水浒传').values('name')
print(ret) #<QuerySet [{'name': '王五'}, {'name': '赵六'}]>
聚合查询
from django.db.models import Avg,Max,Min,Count,Sum
# 聚合查询
'''聚合查询使用aggregate()方法'''
ret = models.Book.objects.all().aggregate(Avg('price'))
ret = models.Book.objects.all().aggregate(a=Avg('price'),m=Max('price'))
print(ret,type(ret)) #{'price__avg': 15.0} <class 'dict'>
'''注意结果为字典类型.'''
分组查询
# 统计一下每个出版社出版书的平均价格
# 1.sql查询
select publishs_id,avg(price) from app01_book group by publishs_id;
select avg(app01_book.price) from app01_book inner join app01_publish on
app01_book.publishs_id = app01_publish.id group by app01_publish.name;# 2.分组查询
ret = models.Book.objects.values('publishs_id').annotate(a=Avg('price')) # 方式一ret = models.Publish.objects.annotate(a=Avg('book__price')) # 方式二
# <QuerySet [<Publish: Publish object>, <Publish: Publish object>]>
print(ret.values('a','name'))
F查询
'''F查询针对本表'''
# 查询一下点赞数大于评论数的书籍
'''1.传统方法'''
ret = models.Book.objects.all()
book_list = []
for i in ret:if i.dianzan > i.comment:book_list.append(i)'''2.F查询'''
from django.db.models import F
''''针对本表不同字段数据进行对比时或者本表字典做一些统一修改时使用F查询'''
# 点赞数大于评论数的
ret = models.Book.objects.filter(dianzan__gt=F('comment'))'''F查询也支持统一修改'''
# 所有书籍上调10块
models.Book.objects.all().update(price=F('price')+10) # 支持四则运算
Q查询
'''Q查询 多条件查询的时候用的多'''
from django.db.models import Q
'''
| -- or
& -- and
~ -- not
''''''and与和or或'''
ret = models.Book.objects.filter(Q(comment__gt=30)|Q(dianzan__gt=50))ret = models.Book.objects.filter(Q(comment__gt=30)&Q(dianzan__gt=50))
# 等同于# ret = models.Book.objects.filter(comment__gt=30,dianzan__gt=50)ret = models.Book.objects.filter(Q(comment__gt=30)|Q(dianzan__gt=50),publishDate__year='2018')
# 注意没有Q包裹的条件,写在Q包裹的条件后面.并且Q查询和publishyear之间是and的关系'''Q查询多层嵌套 | 连接的可以看做一组查询条件'''
ret = models.Book.objects.filter(Q(Q(comment__gt=30)|Q(dianzan__gt=50))&Q(xx=11),publishDate__year='2018')'''条件取反:波浪线写在Q前面'''
# 取评论数小于等于30 的,或者点赞数大于50的
ret = models.Book.objects.filter(~Q(comment__gt=30)|Q(dianzan__gt=50))
创建字段的一些参数讲解
# 1.null
'''如果为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False.'''# 2.blank
'''
如果为True,该字段允许不填。默认为False。
要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。
如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。
'''# 3.default
'''
字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用,
如果你的字段没有设置可以为空,那么将来如果我们后添加一个字段,这个字段就要给一个default值
'''# 4.primary_key
'''
如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True,
Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,
否则没必要设置任何一个字段的primary_key=True。
'''# 5.unique
'''如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的'''# 6.choices
'''由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,
默认的表单将是一个选择框而不是标准的文本框,<br>而且这个选择框的选项就是choices 中的选项。'''# 7.db_index
'''如果db_index=True 则代表着为此字段设置数据库索引'''# DatetimeField、DateField、TimeField这个三个时间字段,都可以设置如下属性。# 8.auto_now_add
'''配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库'''# 9.auto_now
'''配置上auto_now=True,每次更新数据记录的时候会更新该字段,标识这条记录最后一次的修改时间'''
ORM执行原生sql语句(了解)
在模型查询API不够用的情况下,我们还可以使用原始的SQL语句进行查询。
Django 提供两种方法使用原始SQL进行查询:一种是使用raw()方法,进行原始SQL查询并返回模型实例;另一种是完全避开模型层,直接执行自定义的SQL语句。
raw()管理器方法用于原始的SQL查询
例子
'''注意:raw()语法查询必须包含主键。得到是RawQuerySet类型数据.也是可迭代数据,里面放的是每条记录的模型类对象'''ret = models.Book.objects.raw('select * from app01_book;') #raw方法只能操作本表数据# <RawQuerySet: select * from app01_book;>for i in ret:print(i.title)
connection模块 执行自定义SQL
'''从django提供的接口中获取数据库连接,然后像使用pymysql模块一样操作数据库。'''
from django.db import connection# conn = pymysql.connect(host=)
cursor = connection.cursor()
cursor.execute('select * from app01_book;')
ret = cursor.fetchall()
print(ret)
ORM中的锁和事务
ORM中的锁
select查询语句上锁
在mysql中create,update,delete语句是默认要上锁的,select查询默认是不上锁的,如果要给select语句上个锁,需要在后面加for update
select * from app01_book for update;
在ORM中,如果想对一个查询上锁,需要使用select_for_update()
models.Book.objects.filter(price=100).select_for_update()
ORM中的事务
装饰器形式添加事务
用法1:给函数做装饰器来使用
from django.db import transaction@transaction.atomic
def viewfunc(request):d1 = {'name':'chao',}username = request.GET.get('name') #name2sid = transaction.savepoint() #创建保存点# This code executes inside a transaction.models.Book.ojects.filter(id=1).select_for_update() do_stuff()try:d1[username] except:#保存点一般是代码运行路基过程中,代码出了问题,需要手动回滚事务时使用transaction.savepoint_rollback(sid) #回滚到保存点return HttpResponse('别瞎搞,滚犊子')
作为上下文管理器来使用
from django.db import transactiondef viewfunc(request):# This code executes in autocommit mode (Django's default).do_stuff() #sql 不在事务里with transaction.atomic(): # This code executes inside a transaction.do_more_stuff() #sql 在事务里do_other_stuff() #不在事务里
Django:ORM单表操作和多表操作、锁和事务相关推荐
- Django ORM 单表操作
默认使用sqllite数据库 创建表 # models.py form django.db import models class Book(models.Model): # 表名book,djang ...
- DJango周总结二:模型层,单表,多表操作,连表操作,数据库操作,事务
django周复习二 1,模型层: 1单表操作: 13个必会操作总结 返回QuerySet对象的方法有 all() filter() exclude() ...
- Django丨ORM - 单表实例
ORM - 单表实例 创建一个项目 django-admin.py startproject app01 在settings.py中修改INSTALLED_APPS INSTALLED_APPS = ...
- ORM单表查询,跨表查询,分组查询
ORM单表查询,跨表查询,分组查询 单表查询之下划线 models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值models.T ...
- Django框架的模型层之多表操作
目录 一 创建模型 二 表记录的增删改 一对多 多对多 三.基于对象的跨表查询 一对一查询(Author 与 AuthorDetail) 一对多查询(publish与book) 多对多查询 (Auth ...
- Django中Model模块的操作-创建各种表结构(上)
Django框架功能齐全自带数据库操作功能,本文主要介绍Django的ORM框架 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLd ...
- django orm关联查询_django中orm的多表查询
一.创建模型 下面我们通过图书管理系统,来设计出每张表之间的对应关系. 通过上图关系,来定义一下我们的模型类. from django.db import models class Book(mode ...
- django orm级联_Django数据表关联关系映射(一对一、一对多、多对多)
我们知道涉及到数据表之间的对应关系就会想到一对一.一对多.多对多,在学习 MySQL 数据库时表关系设计是需要重点掌握的知识.Django 中定义了三种关系类型的字段用来描述数据库表的关联关系:一对多 ...
- django 1.8 官方文档翻译:5-2-2 表单素材 ( Media 类)
表单素材 ( Media 类) 渲染有吸引力的.易于使用的web表单不仅仅需要HTML – 同时也需要CSS样式表,并且,如果你打算使用奇妙的web2.0组件,你也需要在每个页面包含一些JavaScr ...
- Django ORM – 多表实例:Django模型Model的定义+模型间关系
Django 对各种数据库提供了很好的支持,包括:PostgreSQL.MySQL.SQLite.Oracle. Django 为这些数据库提供了统一的调用API. 我们可以根据自己业务需求选择不同的 ...
最新文章
- 有哪些好的科研和学习习惯?
- WCF 第五章 会话级别的实例
- R3模擬器版本預覽一下。。暫時沒帶QQ....
- 如何在Linux中恢复一个删除了的文件
- SQL where 1=1 的详细解释
- flink中的table api中的CloseableIterator是什么意思?
- LINUX 对引导加密
- 201521123110《Java程序设计》第5周学习总结
- xcode 设置快捷键 整行上下移动
- 巨坑!这公司的行为,挺适合清明节!
- Social Network 社交网络分析
- 鲨鱼 抓包 oracle,抓包工具wireshark的操作使用
- IOS用标签显示滑块的值
- MATLBA中最小二乘支持向量机原理+实例分析
- java转码mp4的代码_JAVA视频格式转换 avi转mp4
- 用定量测定葡萄糖的方法检测根管微渗漏-供应海藻酸钠修饰聚丙烯酸Alg-PAA 醛基化海藻酸钠(ASA) 海藻酸钠-多聚鸟氨酸-海藻酸(A-PLO-A)定制
- THUSC2018滚粗记
- Dell Optiplex 960 n series 释放SLIC
- ajax hapi上传文件,在hapi框架里使用ajax提交表单数据,但是服务端接收到的数据是空对象。怎么办啊?...
- 离散傅里叶变换----解释的最透彻的|包括定义物理意义