Django之ORM多表操作之增刪改

一.創建表

作者表:
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",to_field="nid",on_delete=models.CASCADE)
    # orm會自動幫你給這個字段名字拼上一個_id,數據庫中字段名稱爲authorDetail_id
	參數解釋:
	    # 注意:
        # 1.x版本默認是級聯的可以不加on_delete=models.CASCADE   但是2.x版本一定要加
        # models.SET_NULL:不做級聯 如果關聯的表AuthorDetail將數據刪除了 那麼Author將爲null
        # 如果關聯的表中有定義id字段可以使用to_field="id字段名" 如果關聯的表中沒有定義id字段 mysql默認會加上id這個字段 這裏的to_field就不用定義,to指向表,to_field指向你關聯的字段
        # 一對一的關係用OneToOneField來建立,這個關係字段寫在兩個表的任意一個表裏面都可以

#作者信息表
class AuthorDetail(models.Model):
    nid = models.AutoField(primary_key=True)
    birthday=models.DateField()
    telephone=models.CharField()
    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() #這裏可以使用CharField 但是使用EmailField方便後續校驗是不是Email格式


#書籍表
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如果是外鍵字段,那麼它自動是int類型
    publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
    #foreignkey裏面可以加很多的參數,都是需要咱們學習的,慢慢來,to指向表,to_field指向你關聯的字段,
    # 不寫這個,默認會自動關聯主鍵字段,on_delete級聯刪除字段名稱不需要寫成publish_id,orm在翻譯foreignkey的時候會自動給你這個字段拼上一個_id,這個字段名稱在數據庫裏面就自動變成了publish_id
    # 與Author表建立多對多的關係,ManyToManyField可以建在兩個模型中的任意一個,
    # 自動創建第三張表,並且注意一點,你查看book表的時候,你看不到這個字段,
    # 因爲這個字段就是創建第三張表的意思,不是創建字段的意思,
    # 所以只能說這個book類裏面有authors這個字段屬性
    authors=models.ManyToManyField(to='Author') #注意不管是一對多還是多對多,寫to這個參數的時候,最後後面的值是個字符串,不然你就需要將你要關聯的那個表放到這個表的上面


上述表關係:
	# 作者表和作者詳細信息表是一對一的關係
	# 作者表和書籍表是多對多的關係
	# 出版社和書籍表是一對多的關係   但是實際業務中不一定是
	# 在orm中可以通過屬性來創建第三張表 authors=models.ManyToManyField(to='Author',)
	# 一對一:models.OneToOneField(to="AuthorDetail",to_field='id',on_delete=models.CASCADE)
	# 一對多:models.ForeignKey(to="Publish",to_field="id",on_delete=models.CASCADE)
	# 多對多:models.ManyToManyField(to='Author',) 自動創建第三張表

這裏django中是使用ManyToManyField來創建第三張表,如果我們單獨創建的話需要這樣:

這張表就是作者和書籍的多對多的關係  這種方式沒法使用orm提供多對多表中的一些操作方法,所以不建議使用
我們直接使用authors=models.ManyToManyField(to='Author',)就會形成第三張表,將來我們直接使用authors來操作第三張表
class BookToAuthor(models.Model):
    book_id = models.ForeignKey(to='Book')
    author_id = models.ForeignKey(to='Author')

創建出來的第三張表:
在這裏插入圖片描述
表關係梳理流程:
在這裏插入圖片描述

二.使用admin給關係表添加記錄

admin後臺創建數據:
之前我們學單表的時候是直接寫代碼添加或者在Python console裏面也可以添加,現在我們學習在admin後臺給表添加數據

from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),  #訪問這個地址就可以到我們的admin後臺
]  

在這裏插入圖片描述
這裏需要用戶名密碼,我們要先創建(命令):createsuperuser
在這裏插入圖片描述要想在我們admin後臺操作這些表,需要在我們APP應用下admin.py文件下註冊表信息:

from django.contrib import admin
from app02 import models

# Register your models here.
admin.site.register(models.Book)
admin.site.register(models.Author)
admin.site.register(models.AuthorDetail)
admin.site.register(models.Publish)
注意:註冊完需要重啓一下我們的項目

在這裏插入圖片描述

三.orm語句增刪改查

orm語句添加數據:

**1.1一對一增加:**

    new_author_detail = models.AuthorDetail.objects.create(
        birthday='2012-12-15',
        telephone='138316464',
        addr='黑龍江哈爾濱'
    )

    方式一:
    models.Author.objects.create(
        name='麻子',
        age=25,
        authorDetail=new_author_detail  #直接寫model對象
    )

    方式二:
    obj= models.AuthorDetail.objects.filter(addr='山西臨汾').first()
    models.Author.objects.create(
        name='麻子',
        age=25,
        authorDetail_id=obj.nid,
    )

**1.2一對多增加:**

    方式一:
    models.Book.objects.create(
        title='張三的牀頭故事',
        publishDate='2019-07-22',
        price=23,
        publishs=models.Publish.objects.get(nid=4)
    )

    方式二:
    obj = models.Publish.objects.get(nid=3)
    models.Book.objects.create(
        title='張三的牀頭故事2',
        publishDate='2019-07-23',
        price=15,
        publishs_id=obj.nid   常用
    )


**1.3多對多增加:**
方式一:
book_obj = models.Book.objects.get(nid=1)
book_obj.authors.add(*[1,2])  #常用

方式二:
author1 = models.Author.objects.get(nid=2)
author2 = models.Author.objects.get(nid=3)
book_obj = models.Book.objects.get(nid=5)
book_obj.authors.add(*[author1, author2])

orm語句刪除數據:

# 一對一和一對多的和單表刪除是一樣的
models.AuthorDetail.objects.get(nid=1).delete()  #級聯刪除
# 需要理解的地方:author表是關聯到authordetail表中,
# 如果authordetail中刪除一條記錄,那麼author表中的記錄也會被刪除
# authordetail表屬於被關聯者
# 總結:表1外鍵關聯到表二,表1刪除,不影響表2,表2刪除會影響表1

models.Author.objects.get(nid=3).delete()
#這裏我刪除author表中的數據是不影響到authordetail表的數據,因爲是author表關聯authordetail表

# 一對多刪除:
models.Publish.objects.get(nid=1).delete()
models.Book.objects.get(nid=3).delete()


#多對多刪除
book_obj = models.Book.objects.get(nid=2)
book_obj.authors.remove(5)     #刪除單個
book_obj.authors.remove(*[5,3])  #刪除多個
book_obj.authors.clear()    #全部刪除
book_obj.authors.set('3')     #清空完了再設置
book_obj.authors.set(['2','3'])  #清空完了再設置多個作者

orm語句更新數據:


```python
# 更新數據:
    # 多對多的更新
    book_obj = models.Book.objects.get(nid=2)
    book_obj.authors.set(['2', '3'])  # 刪除然後更新

    # 一對一的更新:
    obj = models.AuthorDetail.objects.get(nid=2)
    models.Author.objects.filter(nid=2).update(
        name='張勝男',
        age=15,
        authorDetail=models.AuthorDetail.objects.get(nid=10)  #第一種
        authorDetail_id=obj.nid  #第二種
    )
   	# 一對多的更新:
    obj = models.Publish.objects.get(pk=4)  #id可以寫成pk  pk=Primary key
    models.Book.objects.filter(pk=6).update(
        title='b哥的往事2',
        publishs=models.Publish.objects.get(nid=3)  #第一種
        publishs_id=obj.nid  #第二種
    )
  # 級聯更新:一對一和一對多是一樣的
    models.Publish.objects.filter(pk=4).update(
        nid=2,  #沒有級聯更新 報錯  
        #有級聯刪除但是沒有級聯更新
        #報錯信息:(1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`orm`.`app02_book`, CONSTRAINT `app02_book_publishs_id_2f1300e0_fk_app02_publish_nid` FOREIGN KEY (`publishs_id`) REFERENCES `app02_publish` (`nid`))')

    )
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章