一.創建表
作者表:
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`))')
)