django模型层2 多表操作
Posted wqzn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django模型层2 多表操作相关的知识,希望对你有一定的参考价值。
1.多表操作:
1.创建模型:
实例:我们来假定下面这些概念,字段和关系
作者模型:一个作者有姓名和年龄。
作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息。作者详情模型和作者模型之间是一对一的关系(one-to-one)
出版商模型:出版商有名称,所在城市以及email。
书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many)。
模型建立如下:
from django.db import models # Create your models here. class Author(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) age=models.IntegerField() # 与AuthorDetail建立一对一的关系 authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE) class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday=models.DateField() telephone=models.BigIntegerField() addr=models.CharField( max_length=64) class Publish(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.EmailField() class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField( max_length=32) publishDate=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2) # 与Publish建立一对多的关系,外键字段建立在多的一方 publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE) # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors=models.ManyToManyField(to=‘Author‘,)
注意事项:
- 表的名称
myapp_modelName
,是根据 模型中的元数据自动生成的,也可以覆写为别的名称 id
字段是自动添加的- 对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
- 这个例子中的
CREATE TABLE
SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。 - 定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加
models.py
所在应用的名称。 - 外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。
2.添加数据库
操作前先简单的录入一些数据:
publish表:
author表:
authordetail表:
一对多
1
2
3
4
5
6
|
方式 1 : publish_obj = Publish.objects.get(nid = 1 ) book_obj = Book.objects.create(title = "金瓶眉" ,publishDate = "2012-12-12" ,price = 100 ,publish = publish_obj) 方式 2 : book_obj = Book.objects.create(title = "金瓶眉" ,publishDate = "2012-12-12" ,price = 100 ,publish_id = 1 ) |
多对多
# 当前生成的书籍对象 book_obj=Book.objects.create(title="追风筝的人",price=200,publishDate="2012-11-12",publish_id=1) # 为书籍绑定的做作者对象 yuan=Author.objects.filter(name="yuan").first() # 在Author表中主键为2的纪录 egon=Author.objects.filter(name="alex").first() # 在Author表中主键为1的纪录 # 绑定多对多关系,即向关系表book_authors中添加纪录 book_obj.authors.add(yuan,egon) # 将某些特定的 model 对象添加到被关联对象集合中。 ======= book_obj.authors.add(*[])
多对多关系其它常用API:
将某个特定的对象从关联的对象集合中去除:
book_obj.authours.remove()
清空被关联的对象集合:
book_obj.authors.clrar()
先清空,在设置:
book_obj.authors.set()
所有的查询:
def select(request):
################基于对象的跨表查询##############
# 1.1对多
# 1.查询linex这本书出版社的名字和邮箱
# book = Book.objects.filter(title="linex").first()
# # pub_obj = Publish.objects.first(nid=book.publish_id).first()
# # print(pub_obj.name)
# print(book.publish.name)
# print(book.publish.email)
# 2
# 查询人民教育出版社出版的所有的书籍的名称
# pub_obj=Publish.objects.get(name="人民教育出版社")
# print(pub_obj.book_set.all().values("title"))
####### 多对多 ##########
# 查询linex这本书籍的作者的年龄
# book=Book.objects.filter(title="linex").first()
# ret=book.authors.all().values("age")
# print(ret)
# #查询alex出版过的所有的书籍名称
# alex=Author.objects.filter(name="alex").first()
# print(alex.book_set.all())
# alex=Author.objects.filter(name="alex").first()
# print(alex.book_set.all())
####### 一对一 ##########
# 查询alex的手机号
# alex=Author.objects.filter(name="alex").first()
# print(alex.ad.tel )
# alex=Author.objects.filter(name="alex").first()
# print(alex.ad.tel)
# # 查询手机号为110的作者的名字
# ad=AuthorDetail.objects.filter(tel=110).first()
# print(ad.author.name)
#########基于双下划线的跨表查询(基于join实现的)#########
# 1
# 查询linex这本书出版社的名字
# ret=Book.objects.filter(title="linex").values("publish__name")
# print(ret)
# pub_obj=Publish.objects.filter(book__title=‘linex‘).values("name")
# print(pub_obj)
# ret=Book.objects.filter(title="linex").values("publish__name")
# print(ret)
# ret=Publish.objects.filter(book__title="linex").values("name")
# print(ret)
# 2
# 查询人民教育出版社出版的所有的书籍的名称
# ret=Book.objects.filter(publish__name="人民教育出版社").values("title")
# print(ret)
# ret=Publish.objects.filter(name="人民教育出版社").values("book__title")
# print(ret)
# 3 查询python这本书籍的作者的年龄
# ret=Book.objects.filter(title="linex").values("authors__age")
# print(ret)
# ret=Author.objects.filter(book__title="linex").values("age")
# print(ret)
# ret=Book.objects.filter(title="linex").values("authors__age")
# print(ret)
# ret=Author.objects.filter(book__title="linex").values("age")
# print(ret)
#
# 4 查询alex出版过的所有的书籍名称
# ret=Book.objects.filter(authors__name="alex").values("title")
# print(ret)
# ret=Author.objects.filter(name="alex").values("book__title")
# print(ret)
# 5 查询alex的手机号
# ret=Author.objects.filter(name="alex").values("ad__tel")
# print(ret)
# ret=AuthorDetail.objects.filter(author__name="alex").values("tel")
# print(ret)
# 6 查询手机号为110的作者的名字
# ret=Author.objects.filter(ad__tel=110).values("name")
# print(ret)
# ret=AuthorDetail.objects.filter(tel=110).values("author__name")
# print(ret)
# 查询人民教育出版社出版过的所有书籍的名字以及作者的姓名
# ret=Publish.objects.filter(name="人民教育出版社").values("book__title","book__authors__name")
# print(ret)
# ret=Publish.objects.filter(name="人民教育出版社").values("book__title","book__authors__name")
# print(ret)
# ret=Book.objects.filter(publish__name="人民教育出版社").values("title","authors__name")
# print(ret)
# ret=Book.objects.filter(publish__name="人民教育出版社").values("title","authors__name")
# print(ret)
# 手机号以110开头的作者出版过的所有书籍名称以及出版社名称
# ret=AuthorDetail.objects.filter(tel__startswith=110).values("author__book__title","author__book__publish__name")
# print(ret)
# ret=AuthorDetail.objects.filter(tel=110).values("author__book__title","author__book__publish__name")
# print(ret)
# ret=Book.objects.filter(authors__ad__tel=110).values("title","publish__name")
# print(ret)
# ret=Author.objects.filter(ad__tel=110).values("book__title","book__publish__name")
# print(ret)
################ 聚合 分组 ################
from django.db.models import Avg,Max,Min,Count
# 查询所有书籍的平均价格
# ret=Book.objects.all().aggregate(Avg("price"))
# print(ret)
# # 查询所有书籍的个数
# ret=Book.objects.all().aggregate(c=Count(1))
# print(ret)
# 查询书籍表每一个出版社id以及对应的书籍个数
# ret=Book.objects.annotate(c=Count(1)).values("publish_id","c")
# print(ret)
# 查询每一个部门的名称以及对应员工的平均薪水
# ret=Emp.objects.annotate(c=Avg("salary")).values("dep","c")
# print(ret)
# ret=Emp.objects.values("dep").annotate(c=Avg("salary"))
# print(ret)
# 查询每一个省份的名称以及对应的员工最大年龄
# ret= Emp.objects.values("pro").annotate(c=Max("age"))
# print(ret)
# 跨表分组查询
# 查询每一个出版社的名称以及对应的书籍平均价格
# ret=Publish.objects.annotate(c=Avg("book__price")).values("c","name")
# print(ret)
# 查询每一个作者的名字以及出版的书籍的最高价格
# ret=Author.objects.annotate(M=Max("book__price")).values(‘M‘,"name")
# print(ret)
# 查询每一个书籍的名称以及对应的作者的个数
# ret=Book.objects.annotate(a=Count("authors")).values("title","a")
# print(ret)
# 4
# 查询作者数不止一个的书籍名称以及作者个数
# ret=Book.objects.annotate(c=Count("authors__name")).filter(c__gt=1).values("title","c")
# print(ret)
# ret=Book.objects.annotate(c=Count("authors__name")).filter(c__gt=1).values("title","c")
# print(ret)
# 5 根据一本图书作者数量的多少对查询集 QuerySet进行排序
# ret=Book.objects.annotate(c=Count("authors__name")).order_by("c")
# print(ret)
# 6 统计每一本以py开头的书籍的名称以及作者个数
# ret=Book.objects.filter(title__startswith="li").annotate(c=Count("authors__name"))
# print(ret)
# ret=Book.objects.filter(title__startswith="li").annotate(c=Count("authors__name")).values("title","c")
# print(ret)
################ F 与 Q ################
from django.db.models import F, Q
# # 查询评论数大于100的所有的书籍名称
# ret=Book.objects.filter(comment_count__gt=2000).values("title")
# print(ret)
# # 查询评论数大于2倍点赞数的所有的书籍名称
# ret=Book.objects.filter(comment_count__gt=F("poll_count")*2)
# print(ret)
# 给每一本书籍的价格提升100
ret=Book.objects.all().update(price=100+F("price"))
print(ret)
return HttpResponse("ok")
以上是关于django模型层2 多表操作的主要内容,如果未能解决你的问题,请参考以下文章