Python Django 模型层02
一 模型层常用字段和参数 1.模型表建立常用字段 1. AutoField:int自增主键列。必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列 id = models.AutoField(primary_key=True) 2.CharField:字符串,相当于varchar。必须提供max_length参数,不能超过255。 title = models.CharField(max_length=255) 3.IntegerField:整数类型,范围在 -2147483648 to 2147483647。(一般不用它来存手机号(位数也不够),直接用字符串存,) kucun = models.IntegerField(null=True) # null参数可不填 4.DecimalField:浮点类型。参数1 max_digits表示总共的位数,参数2 decimal_places表示小数的位数 price = models.DecimalField(max_digits=8,decimal_places=2) 5.DateField: create_time = models.DateField() # 不指定auto_now或auto_now_add时,需要自己传参数 关键性的参数: 1.auto_now:每次操作数据 都会自动刷新当前操作的时间 2.auto_now_add:在创建数据的时候 会自动将创建时间记录下来 后续的修改不会影响该字段 2.字段参数 null 用于表示某个字段可以为空。 unique 如果设置为unique=True 则该字段在此表中必须是唯一的 。 db_index 如果db_index=True 则代表着为此字段设置索引。 default 为该字段设置默认值。 3.表与表之间的关系字段 https://www.cnblogs.com/tfzz/p/11537119.html 二 设置Django打印sql语句 在settings.py文件中粘贴即可 LOGGING = { ‘version‘: 1,‘disable_existing_loggers‘: False,‘handlers‘: { ‘console‘:{ ‘level‘:‘DEBUG‘,‘class‘:‘logging.StreamHandler‘,},‘loggers‘: { ‘django.db.backends‘: { ‘handlers‘: [‘console‘],‘propagate‘: True,‘level‘:‘DEBUG‘,} } 三 单表双下滑线查询(相当于新的过滤条件) 1.大于:__gt 小于:__lt 大于等于:__gte 小于等于:__lte #价格 大于 小于 大于等于 小于等于 filter(price__gt=‘90‘) filter(price__lt=‘90‘) filter(price_gte=‘90‘) filter(price_lte=‘90‘) 2.__in:存在与某几个条件中(相当于或的关系) filter(price__in=[‘11‘,‘22‘,‘33‘]) models.Tb1.objects.exclude(id__in=[11,22,33]) # not in 3. __range 在某个范围内(顾头又顾尾) filter(price__range=[50,90]) 4. __contains模糊查询 models.Tb1.objects.filter(name__contains="ven") # 获取name字段包含"ven"的,区分大小写 models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不区分 5.__startswith,__istartswith以什么开头(区分大小写和不区分) 6.__endswith,__iendswith以什么结尾(区分大小写和不区分) 7.date字段可以通过在其后加__year,__month,__day等来获取date的特点部分数据 filter(create_time__year=‘2017‘) # 查询2017年的数据 四 多表操作 1.一对多关系 :一对多字段的增删改查 以(Book表 和出版社Publish表为例,一对多关系,为publish外键)为例: from django.db import models class Book(models.Model): title = models.CharField(max_length=255) price = models.DecimalField(max_digits=8,decimal_places=2) publish_date = models.DateField(auto_now_add=True) # 库存数 kucun = models.IntegerField(null=True) # 卖出数 maichu = models.IntegerField(null=True) publish = models.ForeignKey(to=‘Publish‘) # 默认是跟publish的主键字段做的一对多外键关联 authors = models.ManyToManyField(to=‘Author‘) # 虚拟字段 1.自动创建第三张表 2.帮助orm跨表查询 def __str__(self): return self.title class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32) # email = models.EmailField() # 就是varchar(254) def __str__(self): return self.name 1.增: 针对外键关联的字段 两种添加方式 第一种通过 外键字段_id=值 models.Book.objects.create(title=‘三国演义‘,price=189.99,publish_id=1) 第二种通过 外键字段=对象 publish_obj = models.Publish.objects.filter(pk=2).first() models.Book.objects.create(title=‘红楼梦‘,price=999.99,publish=publish_obj) 2.删 models.Publish.objects.filter(pk=2).delete() # 默认都是级联更新 级联删除 3.改 第一种通过 外键字段_id=值 models.Book.objects.filter(pk=1).update(publish_id=3) 第二种通过 外键字段=对象 publish_obj = models.Publish.objects.filter(pk=2).first() models.Book.objects.filter(pk=1).update(publish=publish_obj) 4.查 .filter() .all() 2.多对多关系:多对多字段的 增删改查 以(Book表 和作者Author表为例,多对多关系authors为外键)为例: 注意:对象点击多对多虚拟字段 会直接跨到多对多的第三张表 from django.db import models # Create your models here. class Book(models.Model): title = models.CharField(max_length=255) price = models.DecimalField(max_digits=8,decimal_places=2) publish_date = models.DateField(auto_now_add=True) # 库存数 kucun = models.IntegerField(null=True) # 卖出数 maichu = models.IntegerField(null=True) publish = models.ForeignKey(to=‘Publish‘) # 默认是跟publish的主键字段做的一对多外键关联 authors = models.ManyToManyField(to=‘Author‘) # 虚拟字段 1.自动创建第三张表 2.帮助orm跨表查询 def __str__(self): return self.title class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() author_detail = models.OneToOneField(to=‘AuthorDetail‘) 1.增:add可以传作者id数字,也可以直接传作者对象,并且支持传多个位置参数(不要混着用) book_obj = models.Book.objects.filter(pk=1).first() book_obj.authors.add(1) book_obj.authors.add(2,3) author_obj = models.Author.objects.filter(pk=1).first() author_obj1 = models.Author.objects.filter(pk=2).first() author_obj2 = models.Author.objects.filter(pk=3).first() book_obj.authors.add(author_obj) book_obj.authors.add(author_obj1,author_obj2) 2.删:remove()括号内既可以传数字 也可以传对象,并且支持传对个 逗号隔开即可 book_obj = models.Book.objects.filter(pk=1).first() book_obj.authors.remove(3) book_obj.authors.remove(1,2) author_obj = models.Author.objects.filter(pk=1).first() author_obj1 = models.Author.objects.filter(pk=2).first() author_obj2 = models.Author.objects.filter(pk=3).first() book_obj.authors.remove(author_obj) book_obj.authors.remove(author_obj1,author_obj2) 3.改:set()括号内 需要传一个可迭代对象 ,可迭代对象中 可以是多个数字组合,也可以是多个对象组合,但是不要混着用!!! # 将主键为1的书籍对象 作者修改为2,3 book_obj = models.Book.objects.filter(pk=1).first() book_obj.authors.set([2,]) book_obj.authors.set([2,3]) # author_obj = models.Author.objects.filter(pk=1).first() # author_obj1 = models.Author.objects.filter(pk=2).first() # author_obj2 = models.Author.objects.filter(pk=3).first() # book_obj.authors.set([author_obj,]) # book_obj.authors.set([author_obj,author_obj1,author_obj2]) 4.查 # 将某本书跟作者的关系全部清空 # book_obj = models.Book.objects.filter(pk=1).first() # book_obj.authors.clear() # 清空当前书籍与作者的所有关系 5.总结: """ add() set() remove() 上面三个都支持传数字 或者对象 并且可以传多个 但是set需要传可迭代对象 clear() clear括号内不需要传任何参数 """ 3.正向和反向跨表查询 正向查询:当前表中存在着另一张要查询表的外键,可以通过? .外键? 跨表查询称之为正向查询。 反向查询:当前表中不存在着另一张要查询表的外键,可以通过? .另一张表名? 跨查询称之为反向查询。 示例表 from django.db import models # Create your models here. class Book(models.Model): title = models.CharField(max_length=255) price = models.DecimalField(max_digits=8,decimal_places=2) publish_date = models.DateField(auto_now_add=True) # 库存数 kucun = models.IntegerField(null=True) # 卖出数 maichu = models.IntegerField(null=True) publish = models.ForeignKey(to=‘Publish‘) # 默认是跟publish的主键字段做的一对多外键关联 authors = models.ManyToManyField(to=‘Author‘) # 虚拟字段 1.自动创建第三张表 2.帮助orm跨表查询 def __str__(self): return self.title class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32) # email = models.EmailField() # 就是varchar(254) def __str__(self): return self.name class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() author_detail = models.OneToOneField(to=‘AuthorDetail‘) def __str__(self): return self.name class AuthorDetail(models.Model): phone = models.BigIntegerField() addr = models.CharField(max_length=64) """ models.py中的模型类__str__方法 必须返回一个字符串形式数据!!! """ def __str__(self): return self.addr #基于对象的正反向查询 正向: 对象.关联字段(外键).字段 /all() 反向: 对象.表名小写(_set).字段/all() 要点:先拿到对象,再通过对象去查对应的外键字段,分两步? 正向查询 1.查询书籍id是1 的出版社名称(一对多) 书籍---->出版社 book_obj = models.Book.objects.filter(pk=1).first() print(book_obj.publish.name) # 对象点外键字段直接跨到另一张表中 print(book_obj.publish.addr) 2.查询书籍id是2 的作者姓名(多对多) 书籍———》作者 book_obj = models.Book.objects.filter(pk=2).first() print(book_obj.authors) # app01.Author.None print(book_obj.authors.all()) res = book_obj.authors.all() for r in res: print(r.name) 反向查询 1.查询出版社是东方出版社出版的书籍(一对多) 出版社———》书籍 publish_obj = models.Publish.objects.filter(name=‘东方出版社‘).first() # print(publish_obj.book_set) # app01.Book.None print(publish_obj.book_set.all()) 6.查询电话号码是130的作者姓名 (一对一) 信息表———》作者 author_detail_obj = models.AuthorDetail.objects.filter(phone=130).first() print(author_detail_obj.author.name) print(author_detail_obj.author.age) #正向和反向查询时结果可能为多个时加上 .all(),反向还要表名小写:表名小写_set.all() # 5.查询作者是jason的写过的所有的书籍(多对多) 作者———》 书 # author_obj = models.Author.objects.filter(name=‘jason‘).first() # print(author_obj.book_set) # app01.Book.None # print(author_obj.book_set.all()) #基于双下换线的正反向查询 正向:按字段,跨表可以在filter,也可以在values中 正向:关联字段(外键)__字段 反向:表名小写__字段 1.查询jason作者的手机号(一对一) 作者——》信息 正向: res=models.Author.objects.filter(name=‘jason‘).values(‘author_detail__phone‘,‘author_detail__addr‘) print(res) 反向: res1 = models.AuthorDetail.objects.filter(author__name=‘jason‘).values(‘phone‘) print(res1) 查询jason这个作者的年龄和手机号 (一对一) 作者——》信息 正向: res=models.Author.objects.filter(name=‘jason‘).values(‘age‘,‘author_detail__phone‘) # 年龄在本表中不需要跨表,手机号不在需要跨表 print(res) 反向: res1=models.AuthorDetail.objects.filter(author__name=‘jason‘).values(‘phone‘,‘author__age‘) # 手机号在本表中不需要跨表,年龄不在需要跨表 print(res1) 2.查询手机号是130的作者年龄(一对一) 正向: res = models.AuthorDetail.objects.filter(phone=130).values(‘author__age‘) print(res) 反向: res1 = models.Author.objects.filter(author_detail__phone=130).values(‘age‘) print(res1) 3.查询书籍id是1 的作者的电话号码 res=models.Book.objects.filter(pk=1).values(‘authors__author_detail__phone‘) # res1 = models.Book.objects.filter(pk=1).values(‘外键字段1__外键字段2__外键字段3__普通字段‘) print(res) """只要表里面有外键字段 你就可以无限制跨多张表""" 4. # 1.查询出版社为北方出版社的所有图书的名字和价格 # res = models.Publish.objects.filter(name=‘北方出版社‘).values(‘book__title‘,‘book__price‘) # print(res) # 2.查询北方出版社出版的价格大于19的书 # res = models.Book.objects.filter(price__gt=19,publish__name=‘北方出版社‘).values(‘title‘,‘publish__name‘) # print(res) 4.聚合查询(aggregate) from django.db.models import Max,Min,Count,Avg,Sum res = models.Book.objects.aggregate(Sum(‘price‘)) res1 = models.Book.objects.aggregate(Avg(‘price‘)) res2 = models.Book.objects.aggregate(Count(‘price‘)) res3 = models.Book.objects.aggregate(Max(‘price‘)) res4 = models.Book.objects.aggregate(Min(‘price‘)) res5=models.Book.objects.aggregate(Max(‘price‘),Min(‘price‘),Count(‘pk‘),Avg(‘price‘),Sum(‘price‘)) print(res5) print(res) print(res1) print(res2) 5.分组 # 分组查询 # 统计每一本书的作者个数 from django.db.models import Max,Sum # res = models.Book.objects.annotate(author_num = Count(‘authors‘)).values(‘author_num‘,‘title‘) # 依据Book分组,author_num为别名 # print(res) # 统计出每个出版社卖的最便宜的书的价格 # res = models.Publish.objects.annotate(mmp = Min(‘book__price‘)).values(‘name‘,‘mmp‘) # print(res) # 统计不止一个作者的图书 # res = models.Book.objects.annotate(author_num=Count(‘authors‘)).filter(author_num__gt=1) # print(res) """ 只要是queryset对象 就可以无限制的调用queryset对象的方法!!! 最最常用的就是对一个已经filter过滤完的数据 再进行更细化的筛选 """ # 查询各个作者出的书的总价格 # res = models.Author.objects.annotate(sp=Sum(‘book__price‘)).values(‘name‘,‘sp‘) # print(res) 6.F查询(获取字段的值) #F查询的本质就是从数据库中获取某个字段的值 # 查询库存数大于卖出数的书籍 """之前查询等号后面的条件都是我们认为输入的 现在变成了需要从数据库中获取数据放在等号后面 """ from django.db.models import F res = models.Book.objects.filter(kucun__gt=F(‘maichu‘)) print(res) # 将书籍库存数全部增加1000 7.Q查询(更改条件之间的关系) # Q查询 from django.db.models import Q # 查询书籍名称是三国演义或者价格是444.44 # res = models.Book.objects.filter(title=‘三国演义‘,price=444.44) # filter只支持and关系 # res1 = models.Book.objects.filter(Q(title=‘三国演义‘),Q(price=444)) # 如果用逗号 那么还是and关系 # res2 = models.Book.objects.filter(Q(title=‘三国演义‘)|Q(price=444)) # 或的关系 # res3 = models.Book.objects.filter(~Q(title=‘三国演义‘)|Q(price=444)) # ~非的关系 # print(res2) # Q高级用法 q = Q() q.connector = ‘or‘ # 修改查询条件的关系 默认是and q.children.append((‘title__contains‘,‘三国演义‘)) # 往列表中添加筛选条件 q.children.append((‘price__gt‘,444)) # 往列表中添加筛选条件 res = models.Book.objects.filter(q) # filter支持你直接传q对象 但是默认还是and关系 print(res) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |