Django(15)外鍵和表關系


外鍵刪除操作

如果一個模型使用了外鍵。那么在對方那個模型被刪掉后,該進行什么樣的操作。可以通過on_delete來指定。可以指定的類型如下:

  1. CASCADE:級聯操作。如果外鍵對應的那條數據被刪除了,那么這條數據也會被刪除。
  2. PROTECT:受保護。即只要這條數據引用了外鍵的那條數據,那么就不能刪除外鍵的那條數據。
  3. SET_NULL:設置為空。如果外鍵的那條數據被刪除了,那么在本條數據上就將這個字段設置為空。如果設置這個選項,前提是要指定這個字段可以為空
  4. SET_DEFAULT:設置默認值。如果外鍵的那條數據被刪除了,那么本條數據上就將這個字段設置為默認值。如果設置這個選項,前提是要指定這個字段一個默認值。
  5. SET():如果外鍵的那條數據被刪除了。那么將會獲取SET函數中的值來作為這個外鍵的值。SET函數可以接收一個可以調用的對象(比如函數或者方法),如果是可以調用的對象,那么會將這個對象調用后的結果作為值返回回去。
  6. DO_NOTHING:不采取任何行為。一切全看數據庫級別的約束。

注意:以上這些選項只是Django級別的,數據級別依舊是RESTRICT
 

表關系

表之間的關系都是通過外鍵來進行關聯的。而表之間的關系,無非就是三種關系:一對一、一對多、多對多等。以下將討論一下三種關系的應用場景及其實現方式。
 

一對多

應用場景:比如文章和作者之間的關系。一個文章只能由一個作者編寫,但是一個作者可以寫多篇文章。文章和作者之間的關系就是典型的多對一的關系
實現方式:一對多,都是通過ForeignKey來實現的。

class User(models.Model):
    username = models.CharField(max_length=20)
    password = models.CharField(max_length=100)

class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    author = models.ForeignKey("User",on_delete=models.CASCADE)

那么以后在給Article對象指定category,就可以使用以下代碼來完成:

article = Article(title='abc',content='123')
author = User(username='jkc',password='123456')
# 要先保存到數據庫中
author.save()
article.author = author
article.save()

並且以后如果想要獲取某個種類下所有的文章,可以通過article_set來實現。示例代碼如下:

user = User.objects.first()
# 獲取第一個用戶寫的所有文章
articles = user.article_set.all()
for article in articles:
    print(article)

 

一對一

  1. 在Django中一對一是通過models.OnetToOneField來實現的。這個OneToOneField其實本質上就是一個外鍵,只不過這個外鍵有一個唯一約束(unique key),來實現一對一。
  2. 以后如果想要反向引用,那么是通過引用的模型的名字轉換為小寫的形式進行訪問。比如以下模型:
 class FrontUser(models.Model):
     username = models.CharField(max_length=200)

 class UserExtension(models.Model):
     school = models.CharField(max_length=100)
     user = models.OneToOneField("FrontUser",on_delete=models.CASCADE)

 # 通過userextension來訪問UserExtension對象
 user = FrontUser.objects.first()
 print(user.userextension)

UserExtension的對象,可以通過user來訪問到對應的user對象。並且FrontUser對象可以使用userextension來訪問對應的UserExtension對象。 如果不想使用Django默認的引用屬性名字。那么可以在OneToOneField中添加一個related_name參數。示例代碼如下:

 class FrontUser(models.Model):
     username = models.CharField(max_length=200)

 class UserExtension(models.Model):
     school = models.CharField(max_length=100)
     user = models.OneToOneField("FrontUser",on_delete=models.CASCADE,related_name='extension')

 # 通過extension來訪問到UserExtension對象
 user = FrontUser.objects.first()
 print(user.extension)

那么以后就FrontUser的對象就可以通過extension屬性來訪問到對應的UserExtension對象。
 

多對多

  1. 應用場景:比如文章和標簽的關系。一篇文章可以有多個標簽,一個標簽可以被多個文章所引用。因此標簽和文章的關系是典型的多對多的關系。
  2. 實現方式:Django為這種多對多的實現提供了專門的Field。叫做ManyToManyField。還是拿文章和標簽為例進行講解。示例代碼如下:
 class Article(models.Model):
     title = models.CharField(max_length=100)
     content = models.TextField()
     tags = models.ManyToManyField("Tag",related_name="articles")

 class Tag(models.Model):
     name = models.CharField(max_length=50)

在數據庫層面,實際上Django是為這種多對多的關系建立了一個中間表。這個中間表分別定義了兩個外鍵,引用到articletag兩張表的主鍵。
在我們使用多對多反向引用添加的時候,只能使用add這種添加方式,比如向文章中添加標簽,示例代碼如下:

article = Article.objects.first()
tag = Tag(name="好看")
tag.save()
article.tag_set.add(tag)  # 向文章中添加標簽tag

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM