Django框架之模型层

Django ORM操作

关键性字段及参数

时间字段:

DateField 年月日
DateTimeField 年月日时分秒

时间字段的参数:

auto_now:每次操作改数据都会自动更新时间
auto_now_add:新增数据的时候会将当前时间自动添加,后续修改该字段不会自动更新

单独的py文件测试ORM操作需要配置的参数

将manage.py文件中的

复制到test.py文件中,并且添加以下代码:

import django
django.setup()
from app01 import models # 这一句话必须在这下面导入

单表操作

新增数据

有两种方式:

修改数据

有两种方式:

删除数据

有两种方式:

查询数据

<1> all(): 查询所有结果
<2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象

res = models.User.objects.filter(name='jason',age=17)
filter内可以放多个限制条件但是需要注意的是多个条件之间是and关系

<3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。(源码就去搂一眼~诠释为何只能是一个对象)
<4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象

res = models.User.objects.exclude(name='jason')

<5> order_by(*field): 对查询结果排序('-id')/('price')

res = models.User.objects.order_by('age') # 默认是升序
res = models.User.objects.order_by('-age') # 可以在排序的字段前面加一个减号就是降序
res = models.User.objects.order_by('name')
res = models.User.objects.order_by('-name')


<6> reverse(): 对查询结果反向排序 >>>前面要先有排序才能反向

res = models.User.objects.order_by('age').reverse()

<7> count(): 返回数据库中匹配查询(QuerySet)的对象数量。

res = models.User.objects.count()
res = models.User.objects.all().count()

<8> first(): 返回第一条记录

res = models.User.objects.all().first()
res = models.User.objects.all()[0] # 不支持负数的索引取值


<9> last(): 返回最后一条记录

res = models.User.objects.all().last()

<10> exists(): 如果QuerySet包含数据,就返回True,否则返回False

res = models.User.objects.all().exists()
res1 = models.User.objects.filter(name='jason',age=3).exists()
print(res,res1)

<11> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列

res = models.User.objects.values('name') # 列表套字典

res = models.User.objects.values('name','age') # 列表套字典

<12> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列

<13> distinct(): 从返回结果中剔除重复纪录

 

 双下划线查询

查询年轻大于44岁的用户
res = models.User.objects.filter(age__gt=44)
print(res)
查询年轻小于44岁的用户
res = models.User.objects.filter(age__lt=44)
print(res)
查询年轻大于等于44岁的用户
res = models.User.objects.filter(age__gte=44)
print(res)
查询年轻小于等于44岁的用户
res = models.User.objects.filter(age__lte=44)
print(res)

查询年龄是44或者22或者73的用户
res = models.User.objects.filter(age__in=[44,22,73])
print(res)

查询年龄在22到44范围内
res = models.User.objects.filter(age__range=[22,44])
print(res)

 多表操作

一对多的书籍记录操作

新增

# 针对外键关联的字段 两种添加方式
第一种通过publish_id

models.Book.objects.create(title='红楼梦',price=66.66,publish_id=1)

第二种通过publish传出版社对象

publish_obj = models.Publish.objects.filter(pk=2).first()
# models.Book.objects.create(title='三国演义',price=199.99,publish=publish_obj)

修改

queryset修改

通过publish_id

通过publish对象

对象修改

通过publish_id

book_obj = models.Book.objects.filter(pk=1).first()
book_obj.publish_id = 3 # 点表中真实存在的字段名
book_obj.save()

通过publish对象
publish_obj = models.Publish.objects.filter(pk=2).first()
book_obj.publish = publish_obj # 点orm中字段名 传该字段对应的表的数据对象
book_obj.save()

删除
# models.Book.objects.filter(pk=1).delete()
# models.Publish.objects.filter(pk=1).delete()

# book_obj = models.Book.objects.filter(pk=3).first()
# book_obj.delete()

 删除书籍直接查询删除即可,删除出版社会级联删除

 多对多的书籍与作者的操作

给书籍绑定与作者之间的关系

一:通过作者id关联
# 添加关系 add:add支持传数字或对象,并且都可以传多个
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.authors.add(1)         #将书籍与id为1的作者关联
book_obj.authors.add(2,3)      #将书籍与id为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()

正向反向概念

一对一
# 正向:author---关联字段在author表里--->authordetail 按字段
# 反向:authordetail---关联字段在author表里--->author 按表名小写
# 查询jason作者的手机号 正向查询
# 查询地址是 :山东 的作者名字 反向查询

# 一对多
# 正向:book---关联字段在book表里--->publish 按字段
# 反向:publish---关联字段在book表里--->book 按表名小写_set.all() 因为一个出版社对应着多个图书

# 多对多
# 正向:book---关联字段在book表里--->author 按字段
# 反向:author---关联字段在book表里--->book 按表名小写_set.all() 因为一个作者对应着多个图书

# 连续跨表
# 查询图书是三国演义的作者的手机号,先查书,再正向查到作者,在正向查手机号

# 基于对象的表查询
# 正向
# 查询书籍是三国演义的出版社邮箱
# 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)

猜你喜欢

转载自www.cnblogs.com/zhangdajin/p/11012094.html
今日推荐