多表操做python
三種關係:一對一,一對多,多對多mysql
1、數據準備,建立表模型git
配置settings,鏈接到數據庫
# settings更改配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'orm03',
'HOST':'127.0.0.1',
'PORT':3306,
'USER':'root',
'PASSWORD':'123'
}
}sql
# 項目中的init寫入: import pymysql pymysql.install_as_MySQLdb()
在應用中的models.py建立模型
from django.db import models數據庫
# 比較經常使用的信息放到這個表裏面 class Author(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) age=models.IntegerField() authorDetail=models.OneToOneField( to="AuthorDetail", to_field="nid", on_delete=models.CASCADE # on_delete=models.SET_NULL()設置不級連刪除,對方刪除後,本身設置爲空 ) # 與AuthorDetail創建一對一的關係(OneToOneField),一對一的這個關係字段寫在兩個表的任意一個表裏面均可以 # 就是foreignkey+unique,只不過不須要咱們本身來寫參數了,而且orm會自動幫你給這個字段名字拼上一個_id,數據庫中字段名稱爲authorDetail_id # 不經常使用的放到這個表裏面 class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday=models.DateField() # telephone=models.BigIntegerField() 不方便之後查詢,須要再轉str查,不如直接用str類型 telephone=models.CharField(max_length=30) addr=models.CharField(max_length=64) # 與Author創建一對一的關係(OneToOneField這個關係字段寫在兩個表的任意一個表裏面均可以) 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() # 至關於CharField,後期可多一層校驗規則,判斷是不是xx.@...這樣的郵箱地址 # 多對多的表關係,在mysql的時候創建這種關係,須要手動建立一個第三張表,而後寫上兩個字段,每一個字段外鍵關聯到另外兩張多對多關係的表;orm的manytomany自動幫咱們建立第三張表,兩種方式創建關係均可以,之後的學習咱們暫時用orm自動建立的第三張表,由於手動建立的第三張表咱們進行orm操做的時候,不少關於多對多關係的表之間的orm語句方法沒法使用 #若是你想刪除某張表,你只須要將這個表註銷掉,而後執行那兩個數據庫同步指令就能夠了,自動就刪除了。 # 與Publish創建一對多的關係 # 與Author創建多對多的關係 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=models.ForeignKey( to="Publish", to_field="nid", on_delete=models.CASCADE ) # 與Publish創建一對多的關係,外鍵字段創建在多的一方,字段publish若是是外鍵字段,那麼它自動是int類型 #foreignkey裏面能夠加不少的參數,to指向表,to_field指向你關聯的字段,不寫這個,默認會自動關聯主鍵字段,on_delete級聯刪除 #字段名稱不須要寫成publish_id,orm在翻譯foreignkey的時候會自動給你這個字段拼上一個_id,這個字段名稱在數據庫裏面就自動變成了publish_id # 與Author表創建多對多的關係,ManyToManyField能夠建在兩個模型中的任意一個,自動建立第三張表,而且注意一點,你查看book表的時候,你看不到這個字段,由於這個字段就是建立第三張表的意思,不是建立字段的意思,因此只能說這個book類裏面有authors這個字段屬性 authors=models.ManyToManyField(to='Author') # 注意不論是一對多仍是多對多,寫to這個參數的時候,最後後面的值是個字符串,否則你就須要將你要關聯的那個表放到這個表的上面
總結:
建立表:django
一對一:# OneToOneField xx = models.OneToOneField( to='表名', to_field='字段名', on_delete=models.CASCADE ) # to_field能夠不寫,默認是關聯到另外一張表的主鍵 # on_delete在1.x版本的django中不用寫,默認是級聯刪除的,2.x版本的django要寫 # on_delete=models.SET_NULL()設置不級連刪除,對方刪除後,本身設置爲空 一對多:# ForeignKey xx = models.ForeignKey( to='表名', to_field='字段名', on_delete=models.CASCADE ) 多對多:# ManyToManyField xx = models.ManyToManyField(to='另一個表名') #這是自動建立第三表 # 還能夠手動建立第三張表,(用在還有其餘一些本身的字段的時候,暫時忽略) # class BookToAuthor(models.Model): # book_id = models.ForeignKey(to='Book') # author_id = models.ForeignKey(to='Author') # xx = models.CharField(max_length=12) 注意:不論是一對多仍是多對多,寫to這個參數的時候,最後後面的值是個字符串,否則你就須要將你要關聯的那個表放到這個表的上面
執行數據庫同步指令:
python manage.py makemigrations
python manage.py migrate
結果以下:app
2、關係表添加記錄
學習
拓展一種添加數據的方式,是django內部提供的一個後臺管理系統翻譯
建立一個超級用戶:
python manage.py createsuperuser3d
Username (leave blank to use 'administrator'): yangzm Email address: Password: 94211314ming.
訪問127.0.0.1:8000/admin/,使用剛註冊好的用戶名、密碼,登陸後臺管理系統
在應用app01下的admin.py註冊咱們要用的表
from django.contrib import admin
from app01 import models # 導入models
# Register your models here. admin.site.register(models.Author) # admin.site.register方法註冊 admin.site.register(models.Publish) admin.site.register(models.Book) admin.site.register(models.AuthorDetail)
從新運行項目,就會發現表已經在後臺的管理系統當中了
點擊裏面的添加按鈕,根據要求,就能夠添加數據了
增
一對一表的增長
一對一關聯的表是:Author表的authorDetail字段關聯的 AuthorDetail表的nid字段
def query(request):
new_author_detail = models.AuthorDetail.objects.create( birthday='1996-02-14', telephone='188753698755', addr='天界大陸' ) # 方式1: models.Author.objects.create( name='liangdao', age='26', authorDetail=new_author_detail # 直接等於對象 ) new_author_obj = models.AuthorDetail.objects.create( birthday='1886-02-14', telephone='18615724935', addr='幽暗密林' ) # 方式2:(經常使用) models.Author.objects.create( name='baobao', age='55', authorDetail_id=new_author_obj.nid # 把對象的id屬性關聯起來 )
一對多的增長
一對多關聯的表是:Book表的publish字段關聯的 Publish表的nid字段
# 方式1:
models.Book.objects.create(
title='回村的誘惑',
publishDate='2018-12-12',
price=88.88,
publish=models.Publish.objects.get(nid=1)
)
# 方式2:(經常使用)
models.Book.objects.create(
title='回村的誘惑2',
publishDate='2000-11-11',
price=45,
publish_id=models.Publish.objects.get(nid=1).nid
)
多對多的增長
多對多關聯的表是:Book表的authors字段關聯的 Author表的nid字段
# 方式1:經常使用
book_obj = models.Book.objects.get(nid=1)
book_obj.authors.add([1,2])
# 方式2:
author1 = models.Author.objects.get(nid=1)
author2 = models.Author.objects.get(nid=3)
book_obj = models.Book.objects.get(nid=2)
book_obj.authors.add([author1, author2])
一對一和一對多的刪除和單表刪除是同樣的
一對多的刪
# Book表一對多關聯Publish表
models.Publish.objects.get(nid=2).delete()
# Publish表刪除數據,影響到Book表
models.Book.objects.get(nid=7).delete()
# Book表刪除數據,不會影響到Publish表
多對多關係的刪除
實際上就是去刪除多對多自動生成的表中的關係的記錄
# Book表多對多的關聯Author表
book_obj = models.Book.objects.get(nid=3)
book_obj.authors.remove(3)
# 先找到book裏id是3的書,而後經過authors屬性刪除做者id是3的數據
book_obj = models.Book.objects.get(nid=3) book_obj.authors.remove(*[2,3]) # 先找到book裏id是3的書,而後經過authors屬性刪除做者id是2和3的數據 book_obj = models.Book.objects.get(nid=3) book_obj.authors.clear() # 先找到book裏id是3的書,而後經過authors屬性找到關係表,刪除全部id是3的書數據 book_obj = models.Book.objects.get(nid=3) book_obj.authors.clear() book_obj.authors.add(*[1,]) # 先刪除全部id是3的書數據,而後給id是3的書加入一個id是1的做者 book_obj = models.Book.objects.get(nid=3) book_obj.authors.set('1') # 一樣完成上述需求,先清空再添加(set必須給個參數,不然報錯) book_obj = models.Book.objects.get(nid=3) book_obj.authors.set(['5','6']) # 刪除而後更新,添加多個注意:
一對一
models.Author.objects.filter(nid=6).update(
name='baoge',
age='16',
authorDetail=models.AuthorDetail.objects.get(nid=5)
# authorDetail_id = 4 兩種方式
)
一對多
models.Book.objects.filter(pk=6).update(
title='回孃家的誘惑',
price=188,
publish=models.Publish.objects.get(pk=2)
models.Publish.objects.filter(pk=2).update( id=4, # 沒有級聯更新,報錯!! ) # 注:默認級聯刪除,級聯更新沒有默認
多對多
# 就是set
book_obj = models.Book.objects.get(nid=3) book_obj.authors.set('1') # 一樣完成上述需求,先清空再添加(set必須給個參數,不然報錯) book_obj = models.Book.objects.get(nid=3) book_obj.authors.set(['5','6']) # 刪除而後更新,添加多個