Django之ORM跨表操作

一、准备数据库

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=6,decimal_places=2)
    create_time=models.DateField()
    memo=models.CharField(max_length=32,default="")
    publish=models.ForeignKey(to="Publish",default=1)       #定义一对多关系,会在book表添加publish_id字段
    author=models.ManyToManyField("Author")                 #定义多对多关系,会专门生成一张book和author的关系表
    def __str__(self):
        return self.title
class Publish(models.Model):
    name=models.CharField(max_length=32)
    email=models.CharField(max_length=32)
class Author(models.Model):
    name=models.CharField(max_length=32)
    def __str__(self):return self.name

#执行下面python语句生成相关表

python3 manage.py makemigrations
python3 manage.py migrate

添加数据后各个表数据如下:

                                                   

  

二、基于对象的跨表查询

1、一对一关系

(1)查询wang的手机号(反向查询,按表名小写)

obj = Author.objects.filter(name="wang").first()                           # 得到name="wang"的作者的对象
print(obj.authordetail.tel)                    # obj.authordetail表名得到作者对应的详细信息对象,再 .tel得到结果 18971232312

(2)查询手机号为13451222125的作者的名字 (正向查询,按字段)

obj = AuthorDetail.objects.filter(tel="13451222125").first()           # 得到tel="13451222125"的作者详细信息的对象
print(obj.author.name)                      # obj.author字段得到作者对象,再 .name得到结果 li

2、一对多关系

(1)查询id=15的书籍的出版社的名称(正向查询,按字段)

book_obj = Book.objects.filter(id=15).first()                  #得到id=15的数的对象
print(book_obj.publish.name)              # book_obj.publish得到书对应的出版社对象,再.name得到出版社的名字 上海出版社

(2)查询天津出版社出版过的书籍名称(反向查询,按表名小写_set)

publish_obj = Publish.objects.filter(name="天津出版社").first()  #得到name="天津出版社"的出版社对象
print(publish_obj.book_set.all())           # 得到出版社出版的书籍的对象集合:<QuerySet [<Book: go>, <Book: 操作系统原理>]>
for book in publish_obj.book_set.all():
    print(book.title)                                #遍历得到结果:go和操作系统原理

3、多对多关系

(1)查询(1)查询书名为go的所有作者的名字(正向查询,按字段)

obj = Book.objects.filter(title="go").first()                    #得到书名为go的对象
for i in obj.author.all():                                                   # obj.author.all()得到对应作者的集合
    print(i.name)                                                              # 遍历得到结果:wang和zhang

(2)查询zhang出版过的所有书籍名称(反向查询,按表名小写_set)

obj = Author.objects.filter(name="zhang").first()               #得到名字为"zhang"的作者的对象
for i in obj.book_set.all():                                 # obj.book_set.all()得到对应书籍的集合
    print(i.title)                                    # 遍历得到结果:go,操作系统原理,Linux,python
    
print(obj.book_set.all().values("title"))             # 结果:<QuerySet [{'title': 'go'}, {'title': '操作系统原理'}, {'title': 'Linux'}, {'title': 'python'}]>

三、基于queryset查询

1、一对一关系

(1)查询wang的手机号(反向查询,按表名小写)

ret = Author.objects.filter(name="wang").values("authordetail__tel")
print(ret)  # 结果:<QuerySet [{'authordetail__tel': '18971232312'}]>

(2)查询手机号为13451222125的作者的名字 (正向查询,按字段)

ret = AuthorDetail.objects.filter(tel="13451222125").values("author__name")
print(ret)  # 结果:<QuerySet [{'author__name': 'li'}]>

2、一对多关系

(1)查询id=15的书籍的出版社的名称(正向查询,按字段)

ret = Book.objects.filter(id=15).values("publish__name")
print(ret)  # 结果:<QuerySet [{'publish__name': '上海出版社'}]>

(2)查询天津出版社出版过的书籍名称(反向查询,按表名小写)

ret = Publish.objects.filter(name="天津出版社").values("book__title")
print(ret)  # 结果:<QuerySet [{'book__title': 'go'}, {'book__title': '操作系统原理'}]>

3、多对多关系

(1)查询(1)查询书名为go的所有作者的名字(正向查询,按字段)

ret = Book.objects.filter(title="go").values("author__name")
print(ret)  # 结果:<QuerySet [{'author__name': 'wang'}, {'author__name': 'zhang'}]>

(2)查询zhang出版过的所有书籍名称(反向查询,按表名小写)

ret = Author.objects.filter(name="zhang").values("book__title")
print(ret)  # 结果:<QuerySet [{'book__title': 'go'}, {'book__title': 'python'}, {'book__title': '操作系统原理'}, {'book__title': 'Linux'}]>

# 查询手机号以1开头的作者出版过的所有书籍名称以及出版社名称

ret=AuthorDetail.objects.filter(tel__startswith="189").values("author__book__title","author__book__publish__name")
print(ret)  #结果是:<QuerySet [{'author__book__title': 'go', 'author__book__publish__name': '天津出版社'}, {'author__book__title': 'css', 'author__book__publish__name': '上海出版社'}, {'author__book__title': '操作系统原理', 'author__book__publish__name': '天津出版社'}, {'author__book__title': 'Linux', 'author__book__publish__name': '河北出版社'}]>

四、聚合和分组

from django.db.models import Avg, Count, Max, Min

1、统计所有书籍的平均价格

ret = Book.objects.all().aggregate(c=Avg("price"))
print(ret)  # 结果是:{'c': 249.5}

2、查询每一个出版社出版的书籍个数

ret = Publish.objects.all().annotate(c=Count("book")).values("name", "c")
print(ret)  # 结果是:<QuerySet [{'name': '北京出版社', 'c': 0}, {'name': '上海出版社', 'c': 2}, {'name': '天津出版社', 'c': 2}, {'name': '河北出版社', 'c': 1}, {'name': '唐山出版社', 'c': 1}]>

3、查询每一个作者出版的书籍的平均价格

ret = Author.objects.all().annotate(price_avg=Avg("book__price")).values("name", "price_avg")
print(ret)  # 结果是:<QuerySet [{'name': 'song', 'price_avg': 252.25}, {'name': 'wang', 'price_avg': 230.0}, {'name': 'li', 'price_avg': 280.0}, {'name': 'zhang', 'price_avg': 280.0}, {'name': 'zhao', 'price_avg': None}, {'name': 'zhou', 'price_avg': None}]>

4、查询每一本书籍名称以及作者的个数

ret = Book.objects.all().annotate(author_num=Count("author")).values("title", "author_num")
print(ret)  # 结果是:<QuerySet [{'title': 'linux', 'author_num': 2}, {'title': 'css', 'author_num': 2}, {'title': 'go', 'author_num': 2}, {'title': '操作系统原理', 'author_num': 3}, {'title': 'Linux', 'author_num': 4}, {'title': 'python', 'author_num': 3}]>

5、查询价格大于200的每一本书籍名称以及作者的个数

ret = Book.objects.filter(price__gt=200).annotate(author_num=Count("author")).values("title", "author_num")
print(ret)  # 结果是:<QuerySet [{'title': 'linux', 'author_num': 2}, {'title': 'go', 'author_num': 2}, {'title': 'python', 'author_num': 3}, {'title': '操作系统原理', 'author_num': 3}, {'title': 'Linux', 'author_num': 4}]>

五、F查询和Q查询

from django.db.models import F,Q

1、F查询

(1)查找comment_num数量大于poll_num的书

ret = Book.objects.filter(comment_num__gt=F("poll_num"))
print(ret)

(2)查找comment_num数量大于10倍的poll_num的书

ret = Book.objects.filter(comment_num__gt=F("read_num") * 10)
print(ret)

(3)把所有书的价格都加100

Book.objects.all().update(price=F("price") + 100)

2、Q查询

(1)查找以Java开头并且价格大于200的书

ret = Book.objects.filter(title__startswith="java", price__gt=200)
print(ret)

(2)查找以Java开头或者价格小于200的书

ret = Book.objects.filter(Q(title__startswith="java") | Q(price__lt=200))
print(ret)

(3)查找2017年出版的Java开头的书或者2017年的价格小于200的书

ret = Book.objects.filter(Q(title__startswith="java") | Q(price__lt=200), create_time__year=2017, )
print(ret)

原文地址:http://blog.51cto.com/qidian510/2106457

时间: 2024-11-06 09:39:39

Django之ORM跨表操作的相关文章

Django学习【第7篇】:Django之ORM跨表操作(聚合查询,分组查询,F和Q查询等)

django之跨表查询及添加记录 一:创建表 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);     一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many). 创建一对一的关系:OneToOne("要绑定关系的表名") 创建一对多的关系:ForeignKey("要绑定关系的表名") 创建多对多的关系:ManyToMany(&qu

Django之ORM跨表操作(聚合查询,分组查询,F和Q查询等)

一:创建表 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);     一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many). 创建一对一的关系:OneToOne("要绑定关系的表名") 创建一对多的关系:ForeignKey("要绑定关系的表名") 创建多对多的关系:ManyToMany("要绑定关系的表名"

python——Django(ORM连表操作)

一对多 class UserType(models.Model): caption = models.CharField(max_length=32) class UserInfo(models.Model): user_type = models.ForeignKey(UserType)# user_type对象中封装id,caption username = models.CharField(max_length=32) age = models.IntegerField() 增: 1.外键

django之ORM跨表

跨表   正:        1. q = UserInfo.objects.all().first()     q.ug.title         2.      UserInfo.objects.values('nid','ug_id')                   UserInfo.objects.values('nid','ug_id','ug__title')          3. UserInfo.objects.values_list('nid','ug_id','ug

Django学习【第6篇】:Django之ORM单表操作(增删改查)

django之数据库表的单表查询 一.添加表记录 对于单表有两种方式 # 添加数据的两种方式 # 方式一:实例化对象就是一条表记录 Frank_obj = models.Student(name ="海东",course="python",birth="2000-9-9",fenshu=80) Frank_obj.save() # 方式二: models.Student.objects.create(name ="海燕",co

17-2 orm单表操作和多表操作

参考:https://www.cnblogs.com/liwenzhou/p/8660826.html 一  ORM单表操作 1 增删改查 1 1. 查询 2 1. 查所有 3 models.Publisher.objects.all() 4 2. 查某个具体的记录 5 models.Publisher.objects.get(id=1) --> 注意查询条件不成立就报错 6 2. 删除一条记录 7 models.Publisher.objects.get(id=1).delete() 8 3.

Django学习手册 - ORM 数据表操作

queryset 数据类型介绍 QuerySet与惰性机制 所谓惰性机制:表名.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它并不会马上执行sql,而是当调用QuerySet的时候才执行. QuerySet特点: <1>  可迭代的 <2>  可切片 <3>  惰性计算和缓存机制 例: info=models.table_name.objects.all()[0:5] #切片 info= models.table

Django框架05 /orm单表操作

目录 Django框架05 /orm单表操作 昨日内容回顾 今日内容 orm单表操作 对象关系映射(object relational mapping) 1.orm介绍 2.增: 3.时间问题 4.删 5.改 6.批量插入 -- bulk_create 7.查询api 8.基于双下划线的模糊查询 -- filter双下划线查询 9.总结 总结1 总结2 Django框架05 /orm单表操作 昨日内容回顾 模板相关 模板继承(母版继承) 1. 创建一个xx.html页面(作为母版,其他页面来继承

ORM多表操作(object与queryset)

ORM多表操作 一.创建模型 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息:作者详情模型和作者模型之间是一对一的关系. 出版商模型:出版商有名称,所在城市以及邮箱. 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系:一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系. from django.db import models class Author(