django模型層2 多表操作
阿新 • • 發佈:2018-10-27
digits 名稱 alt req 最大 app 聚合 員工 postgre
1.多表操作:
1.創建模型:
實例:我們來假定下面這些概念,字段和關系
作者模型:一個作者有姓名和年齡。
作者詳細模型:把作者的詳情放到詳情表,包含生日,手機號,家庭住址等信息。作者詳情模型和作者模型之間是一對一的關系(one-to-one)
出版商模型:出版商有名稱,所在城市以及email。
書籍模型: 書籍有書名和出版日期,一本書可能會有多個作者,一個作者也可以寫多本書,所以作者和書籍的關系就是多對多的關聯關系(many-to-many);一本書只應該由一個出版商出版,所以出版商和書籍是一對多關聯關系(one-to-many)。
模型建立如下:
from django.db importmodels # 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 多表操作