Django之Orm操作数据
Posted yuyafeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django之Orm操作数据相关的知识,希望对你有一定的参考价值。
单表操作
数据表book表
class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=10, decimal_places=2) publish_date = models.DateField(auto_now_add=True) publish = models.ForeignKey(to=‘Publish‘) author = models.ManyToManyField(to=‘Author‘) def __str__(self): return self.title
数据表publish表
class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32) email = models.EmailField(max_length=32)
数据表author表
class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() authordetail = models.OneToOneField(to=‘AuthorDetail‘)
数据表authordetail表
class AuthorDetail(models.Model): addr = models.CharField(max_length=32) phone = models.CharField(max_length=32)
task.py中操作初始化
if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day3.settings") import django django.setup() from app1 import models # 这一句话必须在这下面导入
单表操作
增
create 基于queryset 返回queryset对象 obj = models.Publish.objects.create(name=‘西方方出版社‘,addr=‘西方方‘,email=‘[email protected]‘) models.Book.objects.create(title=‘三国演义‘, price=66.66,publish_id=4) save 基于对象绑定 返回改数据对象 obj = models.Book(title=‘金瓶‘,price=55.55,publish_id=1) obj.save()
改
update 基于queryset 返回修改的条数 models.Book.objects.filter(pk=1).update(price=99.99) save 基于对象绑定 obj为改数据对象 obj = models.Book.objects.filter(pk=1).first() obj.price = 1000 obj.save()
删
delete 基于queryset 返回修改的条数(如有外键也会返回外表删除的条数)
obj = models.Book.objects.get(pk=7).delete() print(obj)
查
all 查全部 返回queryset obj = models.Book.objects.all() first 第一条 返回改数据对象 obj = models.Book.objects.all().first() last 最后一条 返回该数据对象 obj = models.Book.objects.all().first() filter 查条件匹配 返回queryset obj = models.Book.objects.filter(pk=1).first() get 查询一条数据 超过一条或没有则报错 返回对象 obj = models.Book.objects.get(id=1) exists 判断queryset是否有数据 返回True或 False obj = models.Book.objects.filter(pk=1).exists() exclude 除掉匹配的条件所有的数据 返回queryset obj = models.Book.objects.exclude(pk=1) obj = models.Book.objects.exclude(pk=-1) -1为降序 order_by 排序 返回queryset obj = models.Book.objects.all().order_by(‘price‘) reverse 反向排序 返回queryset obj = models.Book.objects.all().order_by(‘price‘).reverse() obj = models.Book.objects.all().reverse() count 统计查出数据的条数 返回int obj = models.Book.objects.all().count() value 查看字段 返回queryset 一个字典序列 只有value中的字段 obj = models.Book.objects.all().values(‘title‘) value 查看字段 返回queryset 一个元组序列 只有value中的字段 obj = models.Book.objects.all().values_list(‘title‘) distinct 返回结果中剔除重复纪录 去重的对象必须是完全相同的数据才能去重 返回queryset obj = models.Book.objects.all().distinct()
双下划线查询
__gt 大于 返回queryset对象 models.Book.objects.filter(price__gt=60) __lt 小于 返回queryset对象 models.Book.objects.filter(price__lt=60) __gte 大于等于 返回queryset对象 models.Book.objects.filter(price__gte=66.66) __lte 小于等于 返回queryset对象 models.Book.objects.filter(price__lte=66.66) __in 在某些数字之内 返回queryset对象 models.Book.objects.filter(price__in=[66.66,77.77]) __range 在两个数字范围内 返回queryset对象 models.Book.objects.filter(price__range=[0,100])
__year 判断年份等于 返回queryset对象 models.Book.objects.filter(publish_date__year=2019)
__month 判断月份等于 返回queryset对象 models.Book.objects.filter(publish_date__month=6)
__day 判断日等于 返回queryset对象 models.Book.objects.filter(publish_date__day=13)
__week_day 判断星期 返回queryset对象 models.Book.objects.filter(publish_date__week_day=4)
__contains 获取字段是否包含xx的数据 返回queryset对象 models.Book.objects.filter(title__contains=‘红‘)
__icontains 获取字段是否包含xx(无视大小写)的数据 返回queryset对象 models.Book.objects.filter(title__icontains=‘E‘)
__startswith 获取字段是否以xx开头的数据 返回queryset对象 models.Book.objects.filter(title__startswith=‘红‘)
__endswith 获取字段是否以xx结尾的数据 返回queryset对象 models.Book.objects.filter(title__endswith=‘梦‘)
多表操作
多表查询
表与表之间的关系
一对一(OneToOneField):一对一字段无论建在哪张关系表里面都可以,但是推荐建在查询频率比较高的那张表里面
一对多(ForeignKey):一对多字段建在多的那一方
多对多(ManyToManyField):多对多字段无论建在哪张关系表里面都可以,但是推荐建在查询频率比较高的那张表里面
ps:如何判断表与表之间到底是什么关系
换位思考
A能不能有多个B
B能不能有多个A
一对多
增 基于id 返回该数据对象 obj = models.Book.objects.create(title=‘葫芦娃‘,price=11.11,publish_id=2) 基于对象 返回该数据对象 publish_obj = models.Publish.objects.filter(pk=1).first() models.Book.objects.create(title=‘凹凸曼‘,price=22.22, publish=publish_obj) 改 基于queryset 返回影响行数 models.Book.objects.filter(pk=1).update(publish_id=3) publish_obj = models.Publish.objects.filter(pk=1).first() models.Book.objects.filter(pk=1).update(publish=publish_obj) 基于对象 book_obj为该对象 book_obj = models.Book.objects.filter(pk=1).first() book_obj.publish_id = 3 book_obj.save() publish_obj = models.Publish.objects.filter(pk=1).first() book_obj.publish = publish_obj book_obj.save() 删 delete 基于queryset 多的一方只是删除该数据 一的一方会将多的一方的关联数据也删除 返回删除的条数(如有外键也会返回外表删除的条数) models.Book.objects.filter(pk=13).delete() book_obj = models.Book.objects.filter(pk=3).first() book_obj.delete()
多对多
# 给书籍绑定与作者之间的关系 # 添加关系 add:add支持传数字或对象,并且都可以传多个 # book_obj = models.Book.objects.filter(pk=3).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=3).first() # # book_obj.authors.add(author_obj) # book_obj.authors.add(author_obj,author_obj1) # 修改书籍与作者的关系 set() set传的必须是可迭代对象!!! # book_obj = models.Book.objects.filter(pk=3).first() # 可以传数字和对象,并且支持传多个 # book_obj.authors.set((1,)) # book_obj.authors.set((1,2,3)) # # author_list = models.Author.objects.all() # book_obj = models.Book.objects.filter(pk=3).first() # book_obj.authors.set(author_list) # 删除书籍与作者的绑定关系 # book_obj = models.Book.objects.filter(pk=3).first() # # book_obj.authors.remove(1) # # book_obj.authors.remove(2,3) # # author_obj = models.Author.objects.all().first() # author_list = models.Author.objects.all() # # book_obj.authors.remove(author_obj) # book_obj.authors.remove(*author_list) # 需要将queryset打散 # 清空 clear() 清空的是你当前这个表记录对应的绑定关系 # book_obj = models.Book.objects.filter(pk=3).first() # book_obj.authors.clear() # 基于对象的表查询 # 正向 # 查询书籍是三国演义的出版社邮箱 # book_obj = models.Book.objects.filter(title=‘三国演义‘).first() # print(book_obj.publish.email) # 查询书籍是金瓶的作者的姓名 # book_obj = models.Book.objects.filter(title=‘金瓶‘).first() # print(book_obj.authors) # app01.Author.None # print(book_obj.authors.all()) # 查询作者为jason电话号码 # user_obj = models.Author.objects.filter(name=‘jason‘).first() # print(user_obj.authordetail.phone) # 反向 # 查询出版社是东方出版社出版的书籍 一对多字段的反向查询 # publish_obj = models.Publish.objects.filter(name=‘东方出版社‘).first() # print(publish_obj.book_set) # app01.Book.None # print(publish_obj.book_set.all()) # 查询作者jason写过的所有的书 多对多字段的反向查询 # author_obj = models.Author.objects.filter(name=‘jason‘).first() # print(author_obj.book_set) # app01.Book.None # print(author_obj.book_set.all()) # 查询作者电话号码是110的作者姓名 一对一字段的反向查询 # authordetail_obj = models.AuthorDetail.objects.filter(phone=110).first() # print(authordetail_obj.author.name) # 基于双下滑线的查询 # 正向 # 查询书籍为三国演义的出版社地址 # res = models.Book.objects.filter(title=‘三国演义‘).values(‘publish__addr‘,‘title‘) # print(res) # 查询书籍为金瓶的作者的姓名 # res = models.Book.objects.filter(title=‘金瓶‘).values("authors__name",‘title‘) # print(res) # 查询作者为jason的家乡 # res = models.Author.objects.filter(name=‘jason‘).values(‘authordetail__addr‘) # print(res) # 反向 # 查询南方出版社出版的书名 # res = models.Publish.objects.filter(name=‘南方出版社‘).values(‘book__title‘) # print(res) # 查询电话号码为120的作者姓名 # res = models.AuthorDetail.objects.filter(phone=120).values(‘author__name‘) # print(res) # 查询作者为jason的写的书的名字 # res = models.Author.objects.filter(name=‘jason‘).values(‘book__title‘) # print(res) # 查询书籍为三国演义的作者的电话号码 # res = models.Book.objects.filter(title=‘三国演义‘).values(‘authors__authordetail__phone‘) # print(res) # 查询jason作者的手机号 # 正向 # res = models.Author.objects.filter(name=‘jason‘).values(‘authordetail__phone‘) # print(res) # 反向 # res = models.AuthorDetail.objects.filter(author__name=‘jason‘).values(‘phone‘) # print(res) # 查询出版社为东方出版社的所有图书的名字和价格 # 正向 # res = models.Publish.objects.filter(name=‘东方出版社‘).values(‘book__title‘,‘book__price‘) # print(res) # 反向 # res = models.Book.objects.filter(publish__name=‘东方出版社‘).values(‘title‘,‘price‘) # print(res) # 查询东方出版社出版的价格大于400的书 # 正向 # res = models.Publish.objects.filter(name="东方出版社",book__price__gt=400).values(‘book__title‘,‘book__price‘) # print(res) # 反向 # res = models.Book.objects.filter(price__gt=400,publish__name=‘东方出版社‘).values(‘title‘,‘price‘) # print(res) # 聚合查询 aggregate from django.db.models import Max,Min,Count,Sum,Avg # 查询所有书籍的作者个数 # res = models.Book.objects.filter(pk=3).aggregate(count_num=Count(‘authors‘)) # print(res) # 查询所有出版社出版的书的平均价格 # res = models.Publish.objects.aggregate(avg_price=Avg(‘book__price‘)) # print(res) # 4498.636 # 统计东方出版社出版的书籍的个数 # res = models.Publish.objects.filter(name=‘东方出版社‘).aggregate(count_num=Count(‘book__id‘)) # print(res) # 分组查询(group_by) annotate # 统计每个出版社出版的书的平均价格 # res = models.Publish.objects.annotate(avg_price=Avg(‘book__price‘)).values(‘name‘,‘avg_price‘) # print(res) # 统计每一本书的作者个数 # res = models.Book.objects.annotate(count_num=Count(‘authors‘)).values(‘title‘,‘count_num‘) # print(res) # 统计出每个出版社卖的最便宜的书的价格 # res = models.Publish.objects.annotate(min_price=Min(‘book__price‘)).values(‘name‘,‘min_price‘) # print(res) # 查询每个作者出的书的总价格 # res = models.Author.objects.annotate(sum_price=Sum(‘book__price‘)).values(‘name‘,‘sum_price‘) # print(res)
以上是关于Django之Orm操作数据的主要内容,如果未能解决你的问题,请参考以下文章