py文件单独调试django ORM的配置

https://www.cnblogs.com/wu-chao/p/8353315.html

1.新建一个py文件
2.代码环境搭建

 1 import os
 2 
 3 if __name__ != '__main__':
 4     exit()
 5 
 6 # 加载django项目的配置信息
 7 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_pro.settings") # 就在manage.py 文件中第8行
 8 # 导Django 并 启动Django项目
 9 import django
10 django.setup()
11 
12 from app01 import models

3.输入需要测试的查询代码

13种查询方法

语法 作用


all()    查询全部
get(字段='xx')    查找指定值的对象 没有结果会报错
filter(条件)     作用同上,没有不会报错 返回列表
exclude(条件)     排除查询,返回不符合条件的所有对象 返回列表
values(字段,)     按字段 返回字段值 返回字典
values_list(字段,)     同上,返回列表,里边是元祖
order_by(字段)     根据指定字段排序
reverse()     反向排序! 前提是已经有顺序才能反序
distinct()     查询结果去重
count()    取查询到的对象 列表个数
first()    第一个
last()    最后一个
exists()    如果返回列表有数据就返回True,否则返回False

实例

 1 import os
 2 
 3 # 在py中测试ORM的代码环境搭建:
 4 if __name__ == '__main__':
 5 # 加载django项目的配置信息
 6 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_pro.settings") # 就在manage.py的第六行
 7 # 导Django 并 启动Django项目
 8 import django
 9 django.setup()
10 
11 from app01 import models
12 
13 # all()查询
14 ret = models.Person.objects.all()
15 print(ret)
16 
17 # get查询 (查询没有对应结果时会报错) 取到对象
18 ret = models.Person.objects.get(name='老王')
19 print(ret)
20 
21 # filter(**kwargs) 同get但不报错, 取到对象列表,可以批量查询
22 # 对象列表 ,在django叫 QuerySet对象
23 ret = models.Person.objects.filter(id=1) # 查询id1的对象列表
24 print(ret[0])
25 
26 # exclude 排除查询 返回列表
27 ret = models.Person.objects.exclude(id=1) # 取除id=1之外的所有
28 print(ret)
29 
30 # values 按字段 来查找返回,该字段的值(列表)里边是字典
31 ret = models.Person.objects.values('id','name')
32 print(ret) # [{'id': 1, 'name': '小张'}, {'id': 2, 'name': '老王'}]
33 
34 # values_list 同上,返回列表,里边是元祖
35 ret= models.Person.objects.values_list('id','name')
36 print(ret) # [(1, '小张'), (2, '老王')]
37 
38 # order_by 根据指定字段排序
39 ret = models.Person.objects.order_by('id')
40 print(ret)
41 
42 # reverse 反向排序! 前提是已经有顺序才能反序
43 ret = models.Person.objects.order_by('id').reverse()
44 print(ret)
45 
46 # distinct() 去重
47 
48 # count() 取 查询到的对象 列表个数
49 
50 # first() 第一个
51 
52 # last() 最后一个
53 
54 # exists() 如果返回列表有数据就返回True,否则返回False

QuerySet与惰性机制

所谓惰性机制:Publisher.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它并不会马上执行sql,而是当调用QuerySet的时候才执行。

QuerySet特点:

       <1>  可迭代的 

       <2>  可切片

  <3>惰性计算和缓存机制

 1 def queryset(request):
 2     books=models.Book.objects.all()[:10]  #切片 应用分页
 3     books = models.Book.objects.all()[::2]
 4     book= models.Book.objects.all()[6]    #索引
 5     print(book.title)
 6     for obj in books:                     #可迭代
 7         print(obj.title)
 8     books=models.Book.objects.all()          #惰性计算--->等于一个生成器,不应用books不会执行任何SQL操作
 9     # query_set缓存机制1次数据库查询结果query_set都会对应一块缓存,再次使用该query_set时,不会发生新的SQL操作;
10     #这样减小了频繁操作数据库给数据库带来的压力;
11     authors=models.Author.objects.all()
12     for author in  authors:
13         print(author.name)
14     print('-------------------------------------')
15     models.Author.objects.filter(id=1).update(name='张某')
16     for author in  authors:
17         print(author.name)
18     #但是有时候取出来的数据量太大会撑爆缓存,可以使用迭代器优雅得解决这个问题;
19     models.Publish.objects.all().iterator()
20     return HttpResponse('OK')

## 增加和查询操作

* 增

 1 def orm(request):
 2     orm2添加一条记录的方法
 3     单表
 4     1、表.objects.create()
 5     models.Publish.objects.create(name='浙江出版社',addr="浙江.杭州")
 6     models.Classify.objects.create(category='武侠')
 7     models.Author.objects.create(name='金庸',sex='',age=89,university='东吴大学')
 8     2、类实例化:obj=类(属性=XX) obj.save()
 9     obj=models.Author(name='吴承恩',age=518,sex='',university='龙溪学院')
10     obj.save()
11     
12     1对多
13     1、表.objects.create()
14     models.Book.objects.create(title='笑傲江湖',price=200,date=1968,classify_id=6, publish_id=6)
15     2、类实例化:obj=类(属性=X,外键=obj)obj.save()
16     classify_obj=models.Classify.objects.get(category='武侠')
17     publish_obj=models.Publish.objects.get(name='河北出版社')
18     注意以上获取得是和 book对象 向关联的(外键)的对象
19     book_obj=models.Book(title='西游记',price=234,date=1556,classify=classify_obj,publish=publish_obj)
20     book_obj.save()
21     
22     多对多
23     如果两表之间存在双向1对N关系,就无法使用外键来描述其关系了;
24     只能使用多对多的方式,新增第三张表关系描述表;
25     book=models.Book.objects.get(title='笑傲江湖')
26     author1=models.Author.objects.get(name='金庸')
27     author2=models.Author.objects.get(name='张根')
28     book.author.add(author1,author2)
29 
30     书籍和作者是多对多关系,
31     切记:如果两表之间存在多对多关系,例如书籍相关的所有作者对象集合,作者也关联的所有书籍对象集合
32     book=models.Book.objects.get(title='西游记')
33     author=models.Author.objects.get(name='吴承恩')
34     author2 = models.Author.objects.get(name='张根')
35     book.author.add(author,author2)
36     #add()   添加
37     #clear() 清空
38     #remove() 删除某个对象
39     return HttpResponse('OK')

根据条件判断,增加 更新

1 根据user=user去查找,如果找到更新 如果没有找到创建defaults={} 中的数据
2             tk = gen_tcoken(username)
3             models.Token.objects.update_or_create(user=user, defaults={'token': tk})

* 删

1 models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据

* 改

1 # 修改方式1 update()
2     models.Book.objects.filter(id=1).update(price=3)
3 
4     #修改方式2 obj.save() 
5     book_obj=models.Book.objects.get(id=1)
6     book_obj.price=5
7     book_obj.save()

* 查

 1 def ormquery(request):
 2     books=models.Book.objects.all()                               #------query_set对象集合 [对象1、对象2、.... ]
 3     books=models.Book.objects.filter(id__gt=2,price__lt=100) 
 4     book=models.Book.objects.get(title__endswith='')            #---------单个对象,没有找到会报错
 5     book1 = models.Book.objects.filter(title__endswith='').first()
 6     book2 = models.Book.objects.filter(title__icontains='').last()
 7     books=models.Book.objects.values('title','price',             #-------query_set字典集合 [{一条记录},{一条记录} ]
 8                                     'publish__name',
 9                                     'date',
10                                     'classify__category',         #切记 正向连表:外键字段___对应表字段
11                                     'author__name',               #反向连表: 小写表名__对应表字段
12                                     'author__sex',                #区别:正向 外键字段__,反向 小写表名__
13                                     'author__age',
14                                     'author__university')
15 
16     books=models.Book.objects.values('title','publish__name').distinct()  
17                                                                   #exclude 按条件排除。。。
18                                                                   #distinct()去重, exits()查看数据是否存在? 返回 true 和false
19     a=models.Book.objects.filter(title__icontains='').  
20     return HttpResponse('OK')

* 连表查询

 1 反向连表查询:
 2     1、通过object的形式反向连表, obj.小写表名_set.all()
 3     publish=models.Publish.objects.filter(name__contains='湖南').first()
 4     books=publish.book_set.all()
 5     for book in  books:
 6         print(book.title)
 7     通过object的形式反向绑定外键关系
 8     authorobj = models.Author.objects.filter(id=1).first()
 9     objects = models.Book.objects.all()
10     authorobj.book_set.add(*objects)
11     authorobj.save()
12     
13     2、通过values双下滑线的形式,objs.values("小写表名__字段")
14     注意对象集合调用values(),正向查询是外键字段__XX,而反向是小写表名__YY看起来比较容易混淆;
15     books=models.Publish.objects.filter(name__contains='湖南').values('name','book__title')
16     authors=models.Book.objects.filter(title__icontains='我的').values('author__name')
17     print(authors)
18     fifter()也支持__小写表名语法进行连表查询:在publish标查询 出版过《笑傲江湖》的出版社
19     publishs=models.Publish.objects.filter(book__title='笑傲江湖').values('name')
20     print(publishs)
21     查询谁(哪位作者)出版过的书价格大于200元
22     authors=models.Author.objects.filter(book__price__gt=200).values('name')
23     print(authors)
24     通过外键字段正向连表查询,出版自保定的书籍;
25     city=models.Book.objects.filter(publish__addr__icontains='保定').values('title')
26     print(city)

 ## 高级操作(牛叉的上下划线)

* 利用双下划线将字段和对应的操作连接起来

 1 # 获取个数
 2 models.Tb1.objects.filter(name='seven').count()
 3 
 4 # 大于,小于
 5 models.Tb1.objects.filter(id__gt=1)              # 获取id大于1的值
 6 models.Tb1.objects.filter(id__gte=1)              # 获取id大于等于1的值
 7 models.Tb1.objects.filter(id__lt=10)             # 获取id小于10的值
 8 models.Tb1.objects.filter(id__lte=10)             # 获取id小于10的值
 9 models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值
10 
11 # in
12 models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
13 models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
14 
15 # isnull
16 Entry.objects.filter(pub_date__isnull=True)
17 
18 # contains
19 models.Tb1.objects.filter(name__contains="ven")
20 models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
21 models.Tb1.objects.exclude(name__icontains="ven")
22 
23 # range
24 models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and
25 
26 # 其他类似
27 startswith,istartswith, endswith, iendswith,
28 
29 # order by
30 models.Tb1.objects.filter(name='seven').order_by('id')    # asc
31 models.Tb1.objects.filter(name='seven').order_by('-id')   # desc
32 
33 # group by
34 from django.db.models import Count, Min, Max, Sum
35 models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
36 SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
37 
38 # limit 、offset
39 models.Tb1.objects.all()[10:20]
40 
41 # regex正则匹配,iregex 不区分大小写
42 Entry.objects.get(title__regex=r'^(An?|The) +')
43 Entry.objects.get(title__iregex=r'^(an?|the) +')
44 
45 # date
46 Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
47 Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))
48 
49 # year
50 Entry.objects.filter(pub_date__year=2005)
51 Entry.objects.filter(pub_date__year__gte=2005)
52 
53 # month
54 Entry.objects.filter(pub_date__month=12)
55 Entry.objects.filter(pub_date__month__gte=6)
56 
57 # day
58 Entry.objects.filter(pub_date__day=3)
59 Entry.objects.filter(pub_date__day__gte=3)
60 
61 # week_day
62 Entry.objects.filter(pub_date__week_day=2)
63 Entry.objects.filter(pub_date__week_day__gte=2)
64 
65 # hour
66 Event.objects.filter(timestamp__hour=23)
67 Event.objects.filter(time__hour=5)
68 Event.objects.filter(timestamp__hour__gte=12)
69 
70 # minute
71 Event.objects.filter(timestamp__minute=29)
72 Event.objects.filter(time__minute=46)
73 Event.objects.filter(timestamp__minute__gte=29)
74 
75 # second
76 Event.objects.filter(timestamp__second=31)
77 Event.objects.filter(time__second=2)
78 Event.objects.filter(timestamp__second__gte=31)

## 其他操作

# extra
# 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'])

# F
from django.db.models import F
models.Tb1.objects.update(num=F('num')+1)


# Q
# 方式一:
Q(nid__gt=10)
Q(nid=8) | Q(nid__gt=10)
Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
# 方式二:
con = Q()
q1 = Q()
q1.connector = 'OR'
q1.children.append(('id', 1))
q1.children.append(('id', 10))
q1.children.append(('id', 9))
q2 = Q()
q2.connector = 'OR'
q2.children.append(('c1', 1))
q2.children.append(('c1', 10))
q2.children.append(('c1', 9))
con.add(q1, 'AND')
con.add(q2, 'AND')

models.Tb1.objects.filter(con)


# 执行原生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()

## ORM连表操作

我们在学习django中的orm的时候,我们可以把一对多,多对多,分为正向和反向查找两种方式。

正向查找:ForeignKey在 UserInfo表中,如果从UserInfo表开始向其他的表进行查询,这个就是正向操作,反之如果从UserType表去查询其他的表这个就是反向操作。

  • 一对多:models.ForeignKey(其他表)
  • 多对多:models.ManyToManyField(其他表)
  • 一对一:models.OneToOneField(其他表)

正向连表操作总结:

所谓正、反向连表操作的认定无非是Foreign_Key字段在哪张表决定的,

Foreign_Key字段在哪张表就可以哪张表使用Foreign_Key字段连表,反之没有Foreign_Key字段就使用与其关联的 小写表名;

1对多:对象.外键.关联表字段,values(外键字段__关联表字段)

多对多:外键字段.all()

反向连表操作总结:

 通过value、value_list、fifter 方式反向跨表:小写表名__关联表字段

通过对象的形式反向跨表:小写表面_set().all()

## 应用场景

一对多:当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)

例如:创建用户信息时候,需要选择一个用户类型【普通用户】【金牌用户】【铂金用户】等。

多对多:在某表中创建一行数据是,有一个可以多选的下拉框

例如:创建用户信息,需要为用户指定多个爱好

原文地址:https://www.cnblogs.com/linkenpark/p/10911126.html