models.py(模型)

from django.db import models# Create your models here.# 书   出版社  作者   作者详情表#  书
class Book(models.Model):title = models.CharField(max_length=32)  # 书名price = models.DecimalField(max_digits=5,decimal_places=2) # 五位数字,两位小数 999.99publish_date = models.DateField(auto_now_add=True)# auto_now = True 每一次修改都自动更新时间; auto_now_add=True 第一次创建时自动填写时间memo = models.CharField(max_length=128)def __str__(self):return self.title# 出版社
class Publisher(models.Model):name = models.CharField(max_length=32)addr = models.CharField(max_length=128)phone = models.IntegerField()def __str__(self):return self.name# 作者表
class Author(models.Model):name = models.CharField(max_length=16)# 作者和作者详情表表示一对一关联的detail = models.OneToOneField(to="AuthorDetail")# 作者和书的关系是多对多books = models.ManyToManyField(to="Book")def __str__(self):return self.name# 作者详情表
class AuthorDetail(models.Model):city = models.CharField(max_length=32)email = models.EmailField()

加数据

关于单表查询

>>>  找书名含有“看见”的书(contains-->包含)
>>>  models.Book.objects.filter(title__contains="看")
---  <QuerySet [<Book: 看见>]># 查找出版日期是2017年的书
>>>  models.Book.objects.filter(publish_date__year="2017")
---   <QuerySet [<Book: 好吗,好的>, <Book: 看见>]># 查找出版日期大于2017年的书
>>>  models.Book.objects.filter(publish_date__year__gt="2017")
--  <QuerySet [<Book: 用我一辈子去忘记>, <Book: 镜子中的世界>]># 查找出版日期是2017年的书名
>>>  models.Book.objects.filter(publish_date__year="2017").values("title")
---    <QuerySet [{'title': '好吗,好的'}, {'title': '看见'}]># 查找价格大于10元的书名和价格
>>>  models.Book.objects.filter(price__gt="10").values("title","price")
---   <QuerySet [{'title': '看见', 'price': Decimal('10.90')},     {'title': '用我一辈子去忘记', 'price': Decimal('15.90')},     {'title': '天空之城', 'price': Decimal('20.90')}]>

# 查找memo为空的书>>>  models.Book.objects.filter(memo__isnull=True)---  <QuerySet []>
# 查询在北京的出版社
>>>   models.Publisher.objects.filter(addr="北京") --- <QuerySet [<Publisher: 天天>]>
# 查找出版社名字以“天”开头的出版社>>> models.Publisher.objects.filter(name__startswith="天")---  <QuerySet [<Publisher: 天天>, <Publisher: 天空之境>]>
>>>  a = models.Book.objects.filter(price__gt="10").values("title","price")
>>>   for i in a:
...           print(i,type(i)){'title': '看见', 'price': Decimal('10.90')} <class 'dict'>
{'title': '用我一辈子去忘记', 'price': Decimal('15.90')} <class 'dict'>
{'title': '天空之城', 'price': Decimal('20.90')} <class 'dict'>>>>  for i in a:...        print(i["price"])
10.90
15.90
20.90

多对多

查询规律(正向,用字段。  反向,用表名)

                   .authors.all()
(Book------------(查所有相关的作者)--------------->Author)<--------(查作者写过所有相关的书籍)------------         .book_set.all()

#  查找书名为"看见"的书
>>> models.Book.objects.filter(title="看见")
--   <QuerySet [<Book: 看见>]>
# 此时找到的是一个对象集合>>>  models.Book.objects.get(title="看见")
---  <Book: 看见>
#  此时找到的是书的对象()>>>  models.Book.objects.get(title="看见").publisher
---   <Publisher: 稻城出版社>   #  对应的是一个出版社的对象>>>  models.Book.objects.get(title="看见").publisher.name
---  '稻城出版社'   # 查找书名为“看见”的出版社的地址
>>>  models.Book.objects.get(title="看见").publisher.addr
---   '云南'(多对多反向查找)表名_set# 查找书名为“看见”的所有作者
# 从书找作者为反向查找  表名_set>>> models.Book.objects.get(title="看见").author_set.all()
---  <QuerySet [<Author: 柴静>, <Author: 小黑>, <Author: 小景>]>#  查找书名为“看见”的所有作者的名字
# 不能直接.name,QuerySet没有这个方法>>> models.Book.objects.get(title="看见").author_set.all().values("name")
----  <QuerySet [{'name': '柴静'}, {'name': '小黑'}, {'name': '小景'}]>#  查找书名是“看见”的作者的邮箱
#  detail是作者与作者详情表一对一关联的
#  双下划线表示跨表>>> models.Book.objects.get(title="看见").author_set.all().values("detail__email")-- <QuerySet [{'detail__email': '11@66'}, {'detail__email': '11@88'}, {'detail__email': '11@99'}]># 查找作者为“柴静”的所有书 (正向找) 直接用字段名(books)
# .books  相当于Django帮你去查询多对多关联的表
>>>  models.Author.objects.get(name="柴静").books.all()
---   <QuerySet [<Book: 看见>, <Book: 用我一辈子去忘记>]>

外键的反向查询>>> models.Publisher.objects.get(name="天天出版社").book_set.all()
---   <QuerySet [<Book: 用我一辈子去忘记>, <Book: 天空之城>]>>>> models.Publisher.objects.get(name="天天出版社").book_set.all().values_list("title","price")
---  <QuerySet [('用我一辈子去忘记', Decimal('15.90')), ('天空之城', Decimal('20.90'))]>>>>  models.Book.objects.filter(publisher__name="天天出版社").values_list("title","price")
----  <QuerySet [('用我一辈子去忘记', Decimal('15.90')), ('天空之城', Decimal('20.90'))]># 由作者找到书
#  l两种查法,查找柴静出版的书的书名及价格
>>> models.Author.objects.get(name="柴静").books.all().values_list("title","price")
---  <QuerySet [('看见', Decimal('10.90')), ('用我一辈子去忘记', Decimal('15.90'))]>>>>  models.Author.objects.filter(name="柴静").values_list("books__title","books__price")
---   <QuerySet [('看见', Decimal('10.90')), ('用我一辈子去忘记', Decimal('15.90'))]># 使用filter得到的是QuerySet .对象列表
values_list是query set的方法get得到的是具体数据对象
对象才能直接.

# 查找书名为"围城"的作者,写过的书
>>>  author_objs = models.Author.objects.filter(books__title="围城")
>>>   for i in author_objs
...             print(i.books.all())
<QuerySet [<Book: 镜子中的世界>, <Book: 围城>]>
<QuerySet [<Book: 用我一辈子去忘记>, <Book: 围城>]>

总结:在上述的论述中,所有的反向的查询的表名均为小写,且需要提醒的是在一对一的反向查询中表名不需要跟set,因为它只有一个对象,通过“.表名”得到的是一个models对象,可以直接查询需要的字段。

聚合函数

aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。如下例:

#查询所有书籍的平均价格
# 实例1:
a = models.Book.objects.all().aggregate(Avg("price"))print(a)  # {'price__avg': 12.066667}
# 实例2:
a = models.Book.objects.all().aggregate(avgprice=Avg("price"))print(a)# {'avgprice': 12.066667}

如果你希望生成不止一个聚合,你可以向aggregate()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:

# 查询所有书籍的平均价格、价格最大小值、价格最大值
a = models.Book.objects.all().aggregate(Avg("price"),Min("price"),Max("price"))print(a)

-- {'price__avg': 12.066667, 'price__min': Decimal('6.90'), 'price__max': Decimal('20.90')}

以上实例中需要按照如下方式引入相应的模块方法: from django.db.models import Avg, MaxMin

分组函数(annotate)

  annotate()为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数)。

  实例1:查询每一个出版社出版过的书籍个数

from django.db.models import Avg,Max,Min,Counta = models.Publisher.objects.all().annotate(num=Count("book__title"))#可以理解为每一个出版社对象增加一个num字段,该字段值是通过聚合函数联表求得
for i in a:    print(i.num)2211

  annotate的返回值是querySet,如果不想遍历对象,可以用上values_list,如下:

a = models.Publisher.objects.all().annotate(num=Count("book__title")).values_list("name","num")
print(a)<QuerySet [('稻城出版社', 2), ('天天出版社', 2), ('天空之境出版社', 1), ('五道口出版社', 1)]>

查询每本书的作者个数

a = models.Book.objects.all().annotate(counts=Count("author__id")).values("title","counts")-- <QuerySet [{'title': '好吗,好的', 'counts': 1}, {'title': '看见', 'counts': 3}, {'title': '用我一辈子去忘记', 'counts': 2}, {'title': '镜子中的世界', 'counts': 3}, {'title': '围城', 'counts': 2}, {'title': '天空之城', 'counts': 2}]>

F查询与Q查询

F查询

上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?

Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。

使用命令建appE:\Django项目\Books>python3 manage.py startapp app02

注册:

#  当你的表里面有2个字段做比较,就用F查询

查找商品的收藏数大于购买数的商品
>>>  models.Goods.objects.all().filter(keep_num__gt=F("buy_num"))
---   <QuerySet [<Goods: 娃哈哈>]># 收藏数比购买数大2倍
>>> models.Goods.objects.all().filter(keep_num__gt=F("buy_num")*2)
---  <QuerySet [<Goods: 小天使>]>

# 将全部购买数增加100
>>>  models.Goods.objects.all().update(buy_num=F("buy_num")+100)
5

引申:

如果需要修改char字段?

如:把所有商品名前面加上“你好”

from django.db.models import Value as V
from django.db.models.functions import Concat
models.Goods.objects.all().update(name=Concat(V("你好"),F("name")))

>>> from django.db.models.functions import Concat
>>> from django.db.models import Value
>>> models.Book.objects.all().update(title=Concat(F("title"), Value("("), Value("666"), Value(")")))

Q查询

filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象

示例一:

查询作者名是柴静为lishi

app01_models.Author.objects.filter(Q(name="柴静")|Q(name="jassin"))
<QuerySet [<Author: 柴静>, <Author: jassin>]>

你可以组合& 和|  操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询。

示例:查询作者名字是柴静并且不是2018年出版的书的书名。

from django.db.models import Q
from app01 import models as app01_models
models.Book.objects.filter(Q(author__name="柴静")&Q(publish_day__year="2018"))

查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。

例如:查询出版年份是2017或2018,书名中带物语的所有书。

>>> models.Book.objects.filter(Q(publish_date__year=2018) | Q(publish_date__year=2017), title__icontains="物语")
<QuerySet [<Book: 番茄物语>, <Book: 香蕉物语>, <Book: 橘子物语>]>

转载于:https://www.cnblogs.com/jassin-du/p/8344194.html

ORM 图书管理系统相关推荐

  1. 图书管理系统之外键的增删改查

    ---恢复内容开始--- 1,图书管理系统的表结构设计 1.1>id,titlev,出版社_id 1.2>ORM外键:press = models.ForignKey(to="P ...

  2. java图书馆管理系统_六天写出来的基于Swing的图书管理系统你不来吐槽一下?

    前段时间学习完了MySQL和JDBC,想着自己做个东西实战一下,于是写了一个烂大街的图书管理系统...但好歹是自己一个人日夜兼程,硬着头皮做出来的还像样的东西,总结一手吧.看的人欢迎吐槽.我会从以下几 ...

  3. Django09:图书管理系统笔记/choices用法/ MTV与MVC模型/多对多三种创建方式

    图书管理系统笔记 redirect括号内可以直接写url 也可以直接写别名 但如果别名需要参数,必须使用reverse解析. choices用法 使用场景:能列举完全的数据 #使用方法:xxx_cho ...

  4. 基于python的图书管理系统测试步骤_Django admin实现图书管理系统菜鸟级教程完整实例...

    Django 有着强大而又及其易用的admin后台,在这里,你可以轻松实现复杂代码实现的功能,如搜索,筛选,分页,题目可编辑,多选框. 简单到,一行代码就可以实现一个功能,而且模块之间耦合得相当完美. ...

  5. 系统业务逻辑书籍_Python框架:Django写图书管理系统(LMS)

    今天我会带大家真正写一个Django项目,对于入门来说是有点难度的,因为逻辑比较复杂,但是真正的知识就是函数与面向对象,这也是培养用Django思维写项目的开始 Django文件配置 Django模版 ...

  6. Python框架:Django写图书管理系统(LMS)

    今天我会带大家真正写一个Django项目,对于入门来说是有点难度的,因为逻辑比较复杂,但是真正的知识就是函数与面向对象,这也是培养用Django思维写项目的开始 Django文件配置 Django模版 ...

  7. python实现gui+mysql图书管理系统_用Python Django框架写一个图书管理系统LMS

    今天我会带大家真正写一个Django项目,对于入门来说是有点难度的,因为逻辑比较复杂,但是真正的知识就是函数与面向对象,这也是培养用Django思维写项目的开始 Django文件配置 Django模版 ...

  8. 根据教程编写及完成图书管理系统项目分享

    使用工具:编译器:Intellij IDEA,数据库:MySQL8.0,Navicat 12,Tomcat:apache-tomcat-8.5.66-windows-x64 (注:部署该系统需要以上工 ...

  9. Django(图书管理系统)

    图书管理系统 注意事项 1.models 要创建好,规划好自己的表,以及各种表关系 2.url正则要写好 3.settings的配置 4.利用bootstarp 进行布局更漂亮哦 5.注意orm  各 ...

最新文章

  1. 数据泄露报告称,1/5 的外部数据泄露事件涉及政府背景(附下载)
  2. 使用公网IP的非80端口访问内网中SharePoint2013的Web站点
  3. oracle表没被锁删不掉,ORACLE查看表被锁和删除锁
  4. Maven中使用tomcat:run 出现错误 org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException...
  5. 不错php文件缓存类,一个不错的PHP文件页面缓存类
  6. Linux中fork函数的作用及用法
  7. .php on line 0,启动禅道项目管理软件时,报PHP Warning: PHP Startup: in Unknown on line 0解决方法...
  8. 好家伙,MacOS 新版本终于删掉自带 Python2,连 Python 死忠粉都叫好!
  9. 前端学习(1685):前端系列实战课程之设置难度
  10. 一文学搞懂阿里开源的微服务新贵Nacos!
  11. Redis缓存穿透、击穿、雪崩来解释个明白
  12. SpringBoot集成Spring Security(2)——自动登录
  13. 计算机另一账户无法使用office,关闭Word文档提示: 如何处理另一个应用程序或用户正在使用的文件?...
  14. 兔子--html,js,php,ASP,ASP.NET,JSP的关系
  15. php压缩图片变成代码的方法,PHP实现压缩图片尺寸并转为jpg格式的方法示例
  16. datagird无法deleteRow
  17. h5+css3简单实现网页端五子棋游戏1.0版
  18. [附源码]计算机毕业设计JAVA 停车场管理系统
  19. 1、junit学习之junit的基本介绍
  20. 使用Xunit进行单元测试

热门文章

  1. Buildroot 系统设置开机密码登录-迅为RK3588开发板
  2. CentOS 7.5上安装 GitLab 最新版CE/EE
  3. 《网络是怎样连接的》第一章第二节:向DNS服务器查询Web服务器的IP地址
  4. 面向智能移动平台的语义定位与建图
  5. 计算机系统是由几部分构成它们分别是什么
  6. Linux minerd木马清除
  7. 房企迎降息春风酝酿涨价 部分房企取消优惠
  8. 系统资源是什么,以及线程什么时候不会释放 共享资源
  9. 学java常忘怎么办_经常忘记事情怎么办?一定要学会这个方法,既简单又实用!...
  10. SPDK/NVMe存储技术分析之理解SGL