ORM操作:
1.单表的增删改查
1.查询
models.Book.object.all() #得到所有书的对象'
models.Book.object.filter(id=1)
models.Book.object.get(id=1)
2.增加
models.Book.object.create(name=" ")
3.删
models.Book.object.get(id=1).delete()
4.修改
book_obj = models.Book.object.get(id=1)
book_obj.name = " "
book_obj.save() #必须要提交一下
2.外键的增删改查
增 , 删,查同上
book_obj = models.Book.object.get(id=1)
boo_obj.publisher 是 这个书关联的出版社的对象
boo_obj.publisher.Id 和我这本书关联的出版社的id值
而boo_obj.publisher_id 是在数据库中存在的字段;为 和我这本书关联的出版社的id值
3. 多对多操作
1. 查id为1的作者都写过的书?
author_obj = models.Author.objects.get(id=1)
author_obj.books.all() --> 和我这个作者关联的所有书对象
2.想给作者绑定多本书?
author_obj = models.Author.objects.get(id=1)
publisher_obj = models.Publisher.object.filter(id_in[1,2,3]) #得到id为1,2,3的出版社对象
author_obj.books.set(publisher_obj ) #把id是1、2、3的书和我这个作者关联上
set 修改作者对应书的对象,是修改多对多的关系的,自动的帮你提交到数据库。
必知必会的属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | < 1 > all (): 查询所有结果 < 2 > filter ( * * kwargs): 它包含了与所给筛选条件相匹配的对象 < 3 > get( * * kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。 < 4 > exclude( * * kwargs): 它包含了与所给筛选条件不匹配的对象; 就是 排除 符合条件的数据 < 5 > values( * field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列 < 6 > values_list( * field): 它与values()非常相似,它返回的是一个元组序列 < 7 > order_by( * field): 对查询结果排序 < 8 > reverse(): 对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。 < 9 > distinct(): 从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),注意只有在PostgreSQL中支持按字段去重。) < 10 > count(): 返回数据库中匹配查询(QuerySet)的对象数量。 < 11 > first(): 返回第一条记录 < 12 > last(): 返回最后一条记录 < 13 > exists(): 如果QuerySet包含数据,就返回 True ,否则返回 False |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # ret = models.Publisher.objects.all().count() # print(ret) #get查询 # ret1 = models.Publisher.objects.get(name='高教园出版社') # ret2 = models.Publisher.objects.filter(name='66') # print(ret1) # print(ret2) # filter,可以查询多个,组合为List,如果查询不到,则返回一个空的列表,但不会报错; #<QuerySet [<Publisher: Publisher_object:高教园出版社>]> # reverse 将一个有序的QuerySet[] 反转顺序 #只有对有序的QuerySet[] 才能调用 reverse # ret = models.Publisher.objects.all().reverse() # ret1 = models.Publisher.objects.all().order_by('id').reverse() # exclude 排除 满足的条件;排除id=2的表的对象 # ret2 = models.Publisher.objects.exclude(id=2) # print(ret2) # # ret = models.Publisher.objects.filter(name__contains='曾辉') # print(ret) |
返回QuerySet对象的方法有:
all()
filter()
exclude()
order_by()
reverse()
distinct()
特殊的QuerySet
values() 返回一个可迭代的字典序列 [{},{}]
values_list() 返回一个可迭代的元祖序列[(),()]
返回具体对象的
get()
first()
last()
返回pool值的方法有:
exists()
返回数字的方法:
count()
QuerySet方法大全
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | ################################################################## # PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET # ################################################################## def all ( self ) # 获取所有的数据对象 def filter ( self , * args, * * kwargs) # 条件查询 # 条件可以是:参数,字典,Q def exclude( self , * args, * * kwargs) # 条件查询 # 条件可以是:参数,字典,Q def select_related( self , * fields) 性能相关:表之间进行join连表操作,一次性获取关联的数据。 总结: 1. select_related主要针一对一和多对一关系进行优化。 2. select_related使用SQL的JOIN语句进行优化,通过减少SQL查询的次数来进行优化、提高性能。 def prefetch_related( self , * lookups) 性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询在Python代码中实现连表操作。 总结: 1. 对于多对多字段(ManyToManyField)和一对多字段,可以使用prefetch_related()来进行优化。 2. prefetch_related()的优化方式是分别查询每个表,然后用Python处理他们之间的关系。 def annotate( self , * args, * * kwargs) # 用于实现聚合group by查询 from django.db.models import Count, Avg, Max , Min , Sum v = models.UserInfo.objects.values( 'u_id' ).annotate(uid = Count( 'u_id' )) # SELECT u_id, COUNT(ui) AS `uid` FROM UserInfo GROUP BY u_id v = models.UserInfo.objects.values( 'u_id' ).annotate(uid = Count( 'u_id' )). filter (uid__gt = 1 ) # SELECT u_id, COUNT(ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1 v = models.UserInfo.objects.values( 'u_id' ).annotate(uid = Count( 'u_id' ,distinct = True )). filter (uid__gt = 1 ) # SELECT u_id, COUNT( DISTINCT ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1 def distinct( self , * field_names) # 用于distinct去重 models.UserInfo.objects.values( 'nid' ).distinct() # select distinct nid from userinfo 注:只有在PostgreSQL中才能使用distinct进行去重 def order_by( self , * field_names) # 用于排序 models.UserInfo.objects. all ().order_by( '-id' , 'age' ) def extra( self , select = None , where = None , params = None , tables = None , order_by = None , select_params = None ) # 构造额外的查询条件或者映射,如:子查询 Entry.objects.extra(select = { 'new_id' : "select col from sometable where othercol > %s" }, select_params = ( 1 ,)) Entry.objects.extra(where = [ 'headline=%s' ], params = [ 'Lennon' ]) Entry.objects.extra(where = [ "foo='a' OR bar = 'a'" , "baz = 'a'" ]) Entry.objects.extra(select = { 'new_id' : "select id from tb where id > %s" }, select_params = ( 1 ,), order_by = [ '-nid' ]) def reverse( self ): # 倒序 models.UserInfo.objects. all ().order_by( '-nid' ).reverse() # 注:如果存在order_by,reverse则是倒序,如果多个排序则一一倒序 def defer( self , * fields): models.UserInfo.objects.defer( 'username' , 'id' ) 或 models.UserInfo.objects. filter (...).defer( 'username' , 'id' ) #映射中排除某列数据 def only( self , * fields): #仅取某个表中的数据 models.UserInfo.objects.only( 'username' , 'id' ) 或 models.UserInfo.objects. filter (...).only( 'username' , 'id' ) def using( self , alias): 指定使用的数据库,参数为别名(setting中的设置) ################################################## # PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS # ################################################## def raw( self , raw_query, params = None , translations = None , using = None ): # 执行原生SQL models.UserInfo.objects.raw( 'select * from userinfo' ) # 如果SQL是其他表时,必须将名字设置为当前UserInfo对象的主键列名 models.UserInfo.objects.raw( 'select id as nid from 其他表' ) # 为原生SQL设置参数 models.UserInfo.objects.raw( 'select id as nid from userinfo where nid>%s' , params = [ 12 ,]) # 将获取的到列名转换为指定列名 name_map = { 'first' : 'first_name' , 'last' : 'last_name' , 'bd' : 'birth_date' , 'pk' : 'id' } Person.objects.raw( 'SELECT * FROM some_other_table' , translations = name_map) # 指定数据库 models.UserInfo.objects.raw( 'select * from userinfo' , using = "default" ) ################### 原生SQL ################### from django.db import connection, connections cursor = connection.cursor() # cursor = connections['default'].cursor() cursor.execute( """SELECT * from auth_user where id = %s""" , [ 1 ]) row = cursor.fetchone() # fetchall()/fetchmany(..) def values( self , * fields): # 获取每行数据为字典格式 def values_list( self , * fields, * * kwargs): # 获取每行数据为元祖 def dates( self , field_name, kind, order = 'ASC' ): # 根据时间进行某一部分进行去重查找并截取指定内容 # kind只能是:"year"(年), "month"(年-月), "day"(年-月-日) # order只能是:"ASC" "DESC" # 并获取转换后的时间 - year : 年 - 01 - 01 - month: 年 - 月 - 01 - day : 年 - 月 - 日 models.DatePlus.objects.dates( 'ctime' , 'day' , 'DESC' ) def datetimes( self , field_name, kind, order = 'ASC' , tzinfo = None ): # 根据时间进行某一部分进行去重查找并截取指定内容,将时间转换为指定时区时间 # kind只能是 "year", "month", "day", "hour", "minute", "second" # order只能是:"ASC" "DESC" # tzinfo时区对象 models.DDD.objects.datetimes( 'ctime' , 'hour' ,tzinfo = pytz.UTC) models.DDD.objects.datetimes( 'ctime' , 'hour' ,tzinfo = pytz.timezone( 'Asia/Shanghai' )) """ pip3 install pytz import pytz pytz.all_timezones pytz.timezone(‘Asia/Shanghai’) """ def none( self ): # 空QuerySet对象 #################################### # METHODS THAT DO DATABASE QUERIES # #################################### def aggregate( self , * args, * * kwargs): # 聚合函数,获取字典类型聚合结果 from django.db.models import Count, Avg, Max , Min , Sum result = models.UserInfo.objects.aggregate(k = Count( 'u_id' , distinct = True ), n = Count( 'nid' )) = = = > { 'k' : 3 , 'n' : 4 } def count( self ): # 获取个数 def get( self , * args, * * kwargs): # 获取单个对象 def create( self , * * kwargs): # 创建对象 def bulk_create( self , objs, batch_size = None ): # 批量插入 # batch_size表示一次插入的个数 objs = [ models.DDD(name = 'r11' ), models.DDD(name = 'r22' ) ] models.DDD.objects.bulk_create(objs, 10 ) def get_or_create( self , defaults = None , * * kwargs): # 如果存在,则获取,否则,创建 # defaults 指定创建时,其他字段的值 obj, created = models.UserInfo.objects.get_or_create(username = 'root1' , defaults = { 'email' : '1111111' , 'u_id' : 2 , 't_id' : 2 }) def update_or_create( self , defaults = None , * * kwargs): # 如果存在,则更新,否则,创建 # defaults 指定创建时或更新时的其他字段 obj, created = models.UserInfo.objects.update_or_create(username = 'root1' , defaults = { 'email' : '1111111' , 'u_id' : 2 , 't_id' : 1 }) def first( self ): # 获取第一个 def last( self ): # 获取最后一个 def in_bulk( self , id_list = None ): # 根据主键ID进行查找 id_list = [ 11 , 21 , 31 ] models.DDD.objects.in_bulk(id_list) def delete( self ): # 删除 def update( self , * * kwargs): # 更新 def exists( self ): # 是否有结果 QuerySet方法大全 |
单表查询之神奇的双下划线
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | models.Tb1.objects. filter (id__gt = 1 , id__lt = 10 ) # 获取id大于1 且 小于10的值 models.Tb1.objects. filter (id__in = [ 11 , 22 , 33 ]) # 获取id等于11、22、33的数据 models.Tb1.objects.exclude(id__in = [ 11 , 22 , 33 ]) # not in models.Tb1.objects. filter (name__contains = "ven" ) # 获取name字段包含"ven"的 models.Tb1.objects. filter (name__icontains = "ven" ) # icontains大小写不敏感 models.Tb1.objects. filter (id__range = [ 1 , 3 ]) # id范围是1到3的,等价于SQL的bettwen and 类似的还有:startswith,istartswith, endswith, iendswith date字段还可以: models.Class.objects. filter (first_day__year = 2017 ) # first_day 为表里面的一个字段; |
单表的外键的正向查找
正向查询:比如book关联publisher,则通过book得到publisher 为正向;反之为反向
1.基于对象
1 2 3 | # book_obj =models.Book.objects.first() # p_name = book_obj.publisher.name # print(p_name) |
2.基于双下划线(跨表)
1 2 3 4 5 | #2,基于跨表查询(即利用双下划线 来跨表查询) # 双下划线 就表示跨了一张表 # book_obj = models.Book.objects.filter(id=5) # p_name = book_obj.values_list("publisher__name") # print(p_name) |
反向查询
1 2 3 4 5 6 7 8 9 10 | #1,基于对象的查询 publisher_obj = models.Publisher.objects.first() #得到一个具体的对象 #表名_set 来反向查询; 表名_set==related_name # book_name = publisher_obj.book_set.all() # print(book_name) #2,基于跨表查询(即利用双下划线 来跨表查询) # publisher_obj = models.Publisher.objects.filter(id=1) #得到的是<QuerySet [<Publisher: Publisher_object:沙河出版社>]> # book_name = publisher_obj.values_list('books__bookname') # print(book_name) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | # #####################基于对象查询(子查询)############################## # 按字段(publish) # 一对多 book -----------------> publish # <---------------- # book_set.all() # 正向查询按字段: # 查询python这本书籍的出版社的邮箱 # python=models.Book.objects.filter(title="python").first() # print(python.publish.email) # 反向查询按 表名小写_set.all() # 苹果出版社出版的书籍名称 # publish_obj=models.Publish.objects.filter(name="苹果出版社").first() # for obj in publish_obj.book_set.all(): # print(obj.title) # 按字段(authors.all()) # 多对多 book -----------------------> author # <---------------- # book_set.all() # 查询python作者的年龄 # python = models.Book.objects.filter(title="python").first() # for author in python.authors.all(): # print(author.name ,author.age) # 查询alex出版过的书籍名称 # alex=models.Author.objects.filter(name="alex").first() # for book in alex.book_set.all(): # print(book.title) # 按字段 authorDetail # 一对一 author -----------------------> authordetail # <---------------- # 按表名 author # 查询alex的手机号 # alex=models.Author.objects.filter(name='alex').first() # print(alex.authorDetail.telephone) # 查询家在山东的作者名字 # ad_list=models.AuthorDetail.objects.filter(addr="shandong") # # for ad in ad_list: # print(ad.author.name) ''' 对应sql: select publish_id from Book where title="python" select email from Publish where nid = 1 ''' # #####################基于queryset和__查询(join查询)############################ # 正向查询:按字段 反向查询:表名小写 # 查询python这本书籍的出版社的邮箱 # ret=models.Book.objects.filter(title="python").values("publish__email") # print(ret.query) ''' select publish.email from Book left join Publish on book.publish_id=publish.nid where book.title="python" ''' # 苹果出版社出版的书籍名称 # 方式1: # ret1 = models.Publish.objects.filter(name="苹果出版社").values("book__title") # print("111111111====>", ret1.query) # # 方式2: # ret2 = models.Book.objects.filter(publish__name="苹果出版社").values("title") # print("2222222222====>", ret2.query) # # # 查询alex的手机号 # # 方式1: # ret = models.Author.objects.filter(name="alex").values("authorDetail__telephone") # # # 方式2: # models.AuthorDetail.objects.filter(author__name="alex").values("telephone") # 查询手机号以151开头的作者出版过的书籍名称以及书籍对应的出版社名称 ; 跨5张表; 都联合起来; # ret = models.Book.objects.filter(authors__authorDetail__telephone__startswith="151").values('title', "publish__name") # print(ret) |
详细的各种ROM查询(点我)
多对多关联关系
方法:
1.create()
创建一个新的对象,保存对象,并将它添加到关联对象集之中,返回新创建的对象。
1 2 | import datetime models.Author.objects.first().book_set.create(title = "番茄物语" , <br>publish_date = datetime.date.today()) |
2.add()
把指定的model对象添加到关联对象集中。
1 2 | author_objs = models.Author.objects. filter (id__lt = 3 ) models.Book.objects.first().authors.add( * author_objs) |
也可以直接添加id
1 | models.Book.objects.first().authors.add( * [ 1 , 2 ]) * 是将 list 的元素打散,然后一个一个的添加 |
3.set()
更新model对象的关联对象
1 2 3 | publisher_obj = models.Publisher. object . filter (id_in[ 1 , 2 , 3 ]) #得到id为1,2,3的出版社对象 author_obj.books. set (publisher_obj ) #把id是1、2、3的书和我这个作者关联上 |
4.remove()
从关联对象集中移除执行的model对象
1 2 | book_obj = models.Book.objects.first() book_obj.authors.remove( 3 ) |
5.clear()
从关联对象集中移除一切对象。
1 2 | book_obj = models.Book.objects.first() book_obj.authors.clear() |
注意:1.对于ForeignKey对象,clear() 和 remove()方法 仅 在 null=True 的时候 才能执行;
2.对于所有类型的关联字段,add()、create()、remove()和clear(),set()都会马上更新数据库。换句话说,在关联的任何一端,都不需要再调用save()方法。
聚合查询和分组查询
聚合(aggregate()) 它返回一个包含一些键值对的字典。;
分组(annotate)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #聚合aggregate from django.db.models import Avg, Sum ,Count, Max , Min # ret = models.Book.objects.all().aggregate(price_avg = Avg('price'),price_sum = Sum('price')) # print(ret) #分组annotate #查询每个作者的书的总价格 # ret = models.Author.objects.all().annotate(price_sum = Sum('book__price')) # for author in ret: # print(author.author_name,author.price_sum) # ret = models.Author.objects.all().annotate(price_sum = Sum('book__price')).values_list('author_name','price_sum') # #返回一个元组列表 # print(ret) #统计出每个出版社买的最便宜的书的价格 # ret = models.Publisher.objects.all().annotate(min_price = Min('books__price')).values_list('name','min_price') # print(ret) #统计不止一个作者的图书 __gt >; __lt < # book_obj = models.Book.objects.all().annotate(num_author=Count('author')).filter(num_author__gt=1).values_list('bookname','num_author') # print(book_obj) #根据一本图书作者数量的多少对查询集 QuerySet进行排序 # book_obj = models.Book.objects.all().annotate(num_author=Count('author')).values_list('bookname', 'num_author') # print(book_obj.order_by('num_author')) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | # #####################聚合和分组############################## #聚合: 统计所有书的总价格; 不扩表的情况下 from django.db.models import Count, Sum ,Avg # ret = models.Book.objects.all().aggregate(sum_price = Sum("price")) # print(ret) #是一个字典 ; {'sum_price': Decimal('554.00')} #分组 #查询每一个出版社的书籍的平均价格 ret1 = models.Publish.objects. all ().annotate(avg_price = Avg( "book__price" )).values( "name" , "avg_price" ) ret2 = models.Publish.objects.values( "name" ).annotate(avg_price = Avg( "book__price" )).values( "name" , "avg_price" ) #select publish.name , Avg(book.price) from publish inner join book on .... group by publish.id,...; # print(ret1) # QuerySet 对象,avg_price 只不过是在连表中多了一个字段; #查询每一个作者出版过多少书 # ret = models.Author.objects.all().annotate(num_book = Count("book")).values("name","num_book") # # ret = models.Author.objects.all().annotate(num_book=Count("book__nid")).values("name", "num_book") # print(ret) #统计不止一个作者的图书名称;先统计每一个图书有多少个作者;然后 把不止一个作者的图书(就是作者的数量大于1的) 这个条件进行过滤; # sql 语句就是 在分组后加上过滤的条件(having) , 在ORM中 分组后用.filter() 其实就是过滤了; ret = models.Book.objects.annotate(author_c = Count( "authors" )). filter (author_c__gt = 1 ).values( "title" , 'author_c' ) print (ret) ''' ORM 关键点: 1.QuerySet 对象 . annotate(); 2.annotate 进行分组统计,按前面select的字段进行group by ; 3.annotate() 返回值依然是 QuerySet 对象,增加了分组统计之后的键值对 ''' |
注意:
values_list 只有QuerySet才有这一属性;
补充:
1. 分组
ORM中values或者values_list 里面写什么字段,就相当于select 什么字段
ret = models.Employee.objects.all().values("dept", "age")
相当于:
SELECT `employee`.`dept`, `employee`.`age` FROM `employee` LIMIT 21; args=()
2. ORM中 annotate 前面是什么就按照什么分组!这是单表的分组
from django.db.models import Avg
ret = models.Employee.objects.values("province").annotate(a=Avg("salary")).values("province", "a") #annotate前面是所有的省,就按照省分组;
相当于:
SELECT `employee`.`province`, AVG(`employee`.`salary`) AS `a` FROM `employee` GROUP BY `employee`.`province` ORDER BY NULL LIMIT 21; args=()
3. extra --> 在执行ORM查询的时候执行额外的SQL语句
# 查询person表,判断每个人的工资是否大于2000
ret = models.Person.objects.all().extra(
select={"gt": "salary > 2000"}
)
相当于:
SELECT (salary > 2000) AS `gt`, `person`.`id`, `person`.`name`, `person`.`salary`, `person`.`dept_id` FROM `person` LIMIT 21; args=()
4. 直接执行原生的SQL语句,类似pymysql的用法
from django.db import connection
cursor = connection.cursor() # 获取光标,等待执行SQL语句
cursor.execute("""SELECT * from person where id = %s""", [1])
row = cursor.fetchone()
print(row)
F查询和Q查询
F查询(通常是两个字段的值做比较)
Q查询(通常是 filter() 等方法中的关键字参数or,而不是and,或者是更复杂的)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #F查询(当要用两个字段的值做比较的时候用) #通常我们是用一个字段的值与常量做比较 # ret = models.Book.objects.filter(kucun__gt=500) # print(ret) # from django.db.models import F #两个字段做比较的时候,另外的一个字段用F包起来,相当于把这个字段里面的值相应的取出来了 # ret = models.Book.objects.filter(kucun__lt=F("sell_num")) # print(ret) #修改操作也可以使用F函数 # models.Book.objects.update(sell_num = F('sell_num')*3) #通常我们是修改数字的操作,但是我们想修改字符串,比如给书的title 后面加上第几版, 即用 Concat来拼接;拼接的内容要用Value包起来 # from django.db.models.functions import Concat # from django.db.models import Value # models.Book.objects.update(bookname = Concat(F('bookname'),Value(' '),Value('Ⅰ版'))) # Q查询(当要用filter过滤的条件是or的时候),通常filet过滤的条件是and<br> #基于类的 from django.db.models import Q # ret = models.Book.objects.filter(kucun__gt=100,price__gt=99) #这里是kucun的数量>100 and price >99 # print(ret) #但是 要表示 kucun的数量 >100 or price >99 # ret = models.Book.objects.filter(Q(kucun__gt=100) | Q(price__gt=99)) # print(ret) #查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。 # 但是,如果出现Q 对象,它必须位于所有关键字参数的前面。也就是关键字的参数必须是在最后面 # ret = models.Book.objects.filter(Q(kucun__gt=100) | Q(price__gt=99),bookname__contains='学') # print(ret)<br> |
1 2 3 4 5 6 7 8 9 | #基于Q对象的,字段可以是字符串. #模糊查询 key_word = request.GET.get( "p" , "") from django.db.models import Q search_q = Q() # 基于对象的Q查询,字段名可以为字符串 for field in self .search_fields: search_q.connector = "or" search_q.children.append((field + "__contains" , key_word),) #传一个元组 (字段,值) data_obj = self .model.objects. filter (search_q) # 模糊查询后的结果,没有传查询字段的话,就过滤为空,相当于不过滤了。 |
锁和事务
select_for_update() 为锁;必须在事务中使用;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # import time # from django.db import transaction # #锁 select_for_update() 要在事务里面使用 ; 事务里面 要么全部执行,要么全部都不执行 # ret = models.Book.objects.select_for_update().filter(kucun__gt=100) # print(ret) # try: # with transaction.atomic(): #原子操作 # new_publisher = models.Publisher.objects.create(name="火星出版社") # # # 创建一本书 # # models.Book.objects.create( # # title="橘子物语", # # price=11.11, # # kucun=10, # # maichu=10, # # publisher_id=1000 # 指定一个不存在的出版社id # # ) # except Exception as error: # print(str(error)) |
在Python脚本中调用Django环境
1 2 3 4 5 6 7 8 9 10 11 | import os if __name__ = = '__main__' : os.environ.setdefault( "DJANGO_SETTINGS_MODULE" , "BMS.settings" ) import django django.setup() from app01 import models books = models.Book.objects. all () print (books) |
Django终端打印SQL语句
在Django项目的settings.py文件中,在最后复制粘贴如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | LOGGING = { 'version' : 1 , 'disable_existing_loggers' : False , 'handlers' : { 'console' :{ 'level' : 'DEBUG' , 'class' : 'logging.StreamHandler' , }, }, 'loggers' : { 'django.db.backends' : { 'handlers' : [ 'console' ], 'propagate' : True , 'level' : 'DEBUG' , }, } } |
更详细的参照(点我)
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 开发的设计和重构,为开发效率服务
· 从零开始开发一个 MCP Server!
· Ai满嘴顺口溜,想考研?浪费我几个小时
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)