Django多表操做

Django多表ORM設計規則

1.關聯的表之間建議創建外鍵,可是能夠取消關聯關係(db_constraint=False)git

2.關聯表之間的外鍵字段建議採用對應類名的全小寫django

3.採用關聯表的主鍵或對象都可以進行操做ide

建立models:

from django.db import models

# Create your models here.


class Book(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=20)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish = models.ForeignKey(to='Publish', to_field='id')
    author = models.ManyToManyField(to='Author')
    publish_date = models.DateField()


class Publish(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    address = models.CharField(max_length=32)


class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)


class AuthorDetail(models.Model):
    id = models.AutoField(primary_key=True)
    age = models.IntegerField()
    sex = models.CharField(max_length=10, default='male')
    author = models.OneToOneField(to='Author')
建立models

一對多關係(增刪改)

注:1.關係中,多依賴於一;2.外鍵關聯默認有級聯刪除,須要手動明確外鍵的級聯刪除(on_delete=models.CASCADE)spa

# 一、增
# 主鍵操做
publish = Publish.objects.create(name='小女孩出版社', address='山東')
publish_id = publish.id
Book.objects.create(name='死亡Python', price=66.66, publish_date='2018-8-8', publish_id=publish_id)

# 對象操做
publish = Publish.objects.first()
Book.objects.create(name='資治通鑑', price=888.88, publish_date='1970-1-1', publish=publish)

# 二、刪
book = Book.objects.last()  # type: Book
book.delete()
Publish.objects.first().delete()

# 三、改
publish = Publish.objects.last()
book = Book.objects.last()  # type: Book
book.publish = publish
book.save()

publish_id = Publish.objects.last().id
Book.objects.filter(name='死亡Python').update(publish_id=publish_id)

一對一關係(增刪改)

注:經過外鍵所在表決定依賴關係設計

# 一、增
detail = AuthorDetail.objects.create(age=8, telephone=13766668888, info='一個字,帥')
Author.objects.create(name="Owen", author_detail=detail)
Author.objects.create(name="Liuxx", author_detail_id=detail.id)  # 三句一塊兒執行,兩個做者使用一條詳情,不知足惟一約束

detail = AuthorDetail.objects.create(age=88, telephone=13722222222, info='一個字,二')
# Author.objects.create(name="Liuxx", author_detail_id=detail.id)

# 二、刪
AuthorDetail.objects.last().delete()

# 三、一對一關係不考慮連表更新

多對多關係(增刪改)

注:1.多對多關係存在關係表,關係表建議採用ManyToManyField字段處理;2.須要手動建立關係表時,在字段中明確through與through_field值。code

#Book 與 Author表都可以單獨操做,關聯關係存在於 關係表
# 問題:若是獲取關係表,經過Book的對象得到author屬性,表明關係表的對象
book = Book.objects.first()  # type: Book
book.author 表明關係表的對象


detail = AuthorDetail.objects.create(age=88, telephone=13744444444, info='一個字,衰')
Author.objects.create(name="Egon", author_detail_id=detail.id)

b1 = Book.objects.first()  # type: Book
b2 = Book.objects.all()[1]  # type: Book
a1 = Author.objects.first()  # type: Author
a2 = Author.objects.all()[1]  # type: Author


# 一、增 add()
book.author.add(*authors)

b1.author.add(a1.id, a2.id)
b2.author.add(a1, a2)

# 二、刪
# 將第二本書的關係記錄所有清除
b2.author.clear()

# 經過 主鍵 或 對象 操做指定某條記錄
b1.author.remove(a1)
b1.author.remove(a2.id)

# 三、改
# 清除該本書的以前全部關係記錄,添加新的關係
b1.author.clear()
b1.author.add(a1)

# 去除新數據中不存在的值,添加新數據中新有的值,與以前重複的值保留
b2.author.set([a2.id])

a3 = Author.objects.last()
b2.author.set([a2.id, a3.id])

跨表查詢

1.正向逆向概念:從存放外鍵的表到關係表稱之爲正向跨表查詢,反之稱爲逆向跨表查詢;對象

2.正向查詢經過外鍵屬性名進行跨表查詢;blog

3.逆向查詢經過關聯表對應類名小寫進行跨表查詢。ci

基於對象的跨表查詢:

在跨表查詢的規則上,跨表查詢的結果爲多條數據時須要在字段後添加_set。rem

# 一、一對多表查詢
# 需求:打印第一本書的出版社名
# book = Book.objects.first()  # type:
# print(book.publish.name)

# 需求:第一個出版社出版過的書們的名字,
# publish = Publish.objects.first()
# print(publish.book_set.all())
# for book in publish.book_set.all():
#     print(book.name)


# 需求:打印第二本書的出版社地址
# address = Book.objects.all()[1].publish.address
# print(address)

# 需求:第二個出版社出版過的書們的價格
# publish = Publish.objects.all()[1]  # type: Publish
# for book in publish.book_set.all():
#     print(book.price)

# 二、一對一
# author = Author.objects.first()  # type: Author
# print(author.author_detail.telephone)

# author_detail = AuthorDetail.objects.last()   # type: AuthorDetail
# print(author_detail.author.name)


# 三、多對多
# 需求:第一本書的做者們的姓名
# book = Book.objects.filter(name="資治通鑑").first()  # type: Book
# # print(book.author)
# for author in book.author.filter(name__endswith="xx"):
#     print(author.name)

# 四、
# 需求:第二個做者寫過的書們的書名
# author = Author.objects.all()[1]   # type: Author
# for book in author.book_set.all():
#     print(book.name)

# 需求:第一個出版社出版過的書們的名字與價格
# publish = Publish.objects.first()
# books = publish.book_set.all()  # 數據全部字段數據都被保留存放在對象(們)中
# for book in books:
#     print(book.name, book.price)

# books_infos = publish.book_set.values('name', 'price')  # 數據指定字段數據被保留存放在列表中
# print(books_infos)


# 五、多級跨表查詢
# 需求:第一個出版社出版過書們的做者們的電話號碼
# publish = Publish.objects.first()  # type: Publish
# books = publish.book_set.all()
# for book in books:  # type: Book
#     authors = book.author.all()  # type: Author
#     for author in authors:  # type: Author
#         print(author.author_detail.telephone)

基於雙下劃線的跨表查詢:

注:filter方法與values方法支持__查詢規則。

# 一、一對多
# 需求:第一本書的出版社名
# publish_name =  Book.objects.filter(id=5).values('publish__name')
# print(publish_name)

# 需求:第一個出版社出版過的書們,
# books_infos = Publish.objects.filter(id=2).values('book__name', 'book__price')
# print(books_infos)


# 二、一對一
# 需求: 查詢全部大於80歲做者的名字與實際年齡
# authors_infos =  Author.objects.filter(author_detail__age__gt=80).values('name', 'author_detail__age')
# print(authors_infos)


# 多級連表查詢
# 多表關聯:查詢出版社在上海的出版過的全部書的 做者姓名、做者電話、具體出版社名 的相關信息
# infos = Publish.objects.filter(address__contains='上海').values('book__author__name', 'book__author__author_detail__telephone', 'name')
# print(infos)
相關文章
相關標籤/搜索