16.表關係

 

一對多

  1. 應用場景:好比文章和做者之間的關係。一個文章只能由一個做者編寫,可是一個做者能夠寫多篇文章。文章和做者之間的關係就是典型的多對一的關係。
  2. 實現方式:一對多或者多對一,都是經過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對象指定author,就可使用如下代碼來完成:javascript

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

而且之後若是想要獲取某個用戶下全部的文章,能夠經過article_set來實現。示例代碼以下:html

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

而且若是想要將文章添加到某個分類中。可使用一下的方式:java

category = Category.objects.first()

article = Article(title='bbb',content='vvv')
article.author = FrontUser.objects.first()

category.article_set.add(article,bulk=False)


使用bulk=False,那麼Django會自動的保存article,而不須要在添加到category以前先保存article。
或者是另一種解決方式是,在添加到category.article_set中以前,先將article保存到數據庫中。可是若是article.category不能爲空,那麼就產生一種死循環了,article沒有category不能保存,而將article添加到cateogry.artile_set中,又須要article以前是已經存儲到數據庫中的。
* 若是是上面的那種需求,建議使用bulk=False的解決方案。python

一對一

  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. 應用場景:好比文章和標籤的關係。一篇文章能夠有多個標籤,一個標籤能夠被多個文章所引用。所以標籤和文章的關係是典型的多對多的關係。ios

  2. 實現方式:Django爲這種多對多的實現提供了專門的Field。叫作ManyToManyField。仍是拿文章和標籤爲例進行講解。示例代碼以下:web

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兩張表的主鍵。數據庫

相關文章
相關標籤/搜索