一 模型层常用字段和参数
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中
反向:按表名小写,也可以在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)
#F查询的本质就是从数据库中获取某个字段的值 # 查询库存数大于卖出数的书籍 """之前查询等号后面的条件都是我们认为输入的 现在变成了需要从数据库中获取数据放在等号后面 """ from django.db.models import F res = models.Book.objects.filter(kucun__gt=F(‘maichu‘)) print(res)
# 将书籍库存数全部增加1000
# models.Book.objects.update(kucun=F(‘kucun‘)+1000)
# 把所有书名后面加上‘新款‘
# from django.db.models.functions import Concat
# from django.db.models import Value
#
# ret3 = models.Book.objects.update(title=Concat(F(‘title‘),Value(‘新款‘)))
# models.Book.objects.update(title = F(‘title‘)+‘新款‘) # 不能这么写
# 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)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。