7、Django的orm之多表操做(一)

多表操做python

三種關係:一對一,一對多,多對多mysql

1、數據準備,建立表模型git

  1. 配置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()
  2. 在應用中的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這個參數的時候,最後後面的值是個字符串,否則你就須要將你要關聯的那個表放到這個表的上面
  3. 執行數據庫同步指令:
    python manage.py makemigrations
    python manage.py migrate
    結果以下:app

2、關係表添加記錄
學習

拓展一種添加數據的方式,是django內部提供的一個後臺管理系統翻譯

  1. 建立一個超級用戶:
    python manage.py createsuperuser3d

    Username (leave blank to use 'administrator'):  yangzm
    Email address:  
    Password:  94211314ming.
  2. 訪問127.0.0.1:8000/admin/,使用剛註冊好的用戶名、密碼,登陸後臺管理系統

  3. 在應用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)
  4. 從新運行項目,就會發現表已經在後臺的管理系統當中了

  5. 點擊裏面的添加按鈕,根據要求,就能夠添加數據了

  • 一對一表的增長
    一對一關聯的表是: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])

一對一和一對多的刪除和單表刪除是同樣的

  • 一對一的刪
    # Author表一對一關聯AuthorDetail表
    models.AuthorDetail.objects.get(nid=2).delete()
    # 當AuthorDetail表刪除數據時,會影響到Author表,由於級聯刪除
    models.Author.objects.get(nid=4).delete()
    # 當Author表刪除數據時,不會影響到AuthorDetail表
    注意:
    • 表一關聯表二,作了級聯,表二刪除,表一跟着刪除
    • 表一關聯表二,沒作級聯,表二刪除,表一報錯
    • 表一關聯表二,不管作沒作級聯,表一刪除數據,都不會影響到表二
  • 一對多的刪
    # 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']) 
        # 刪除而後更新,添加多個
    注意:
    • Book表刪除數據,會影響到關係表的數據
    • Author表刪除數據,也一樣會影響到關係表的數據
  1. 更新
  • 一對一
    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']) 
        # 刪除而後更新,添加多個
相關文章
相關標籤/搜索