1. 程式人生 > >django模型多對一 多對多 一對一三種關係解讀

django模型多對一 多對多 一對一三種關係解讀

django模型 資料庫設計學習

作用:設計的好,會清晰,且易於理解,後續開發也事半功倍,易於維護。
基本原則
1. 一對一的表,兩表的屬性實際上完全可以合併成一個表,共用一個主鍵即可;
2. 一對多的表,可以設中間關聯表,也可以將關聯表併入“多”這頭;若設獨立關聯表,則可引入“多”這頭的主鍵作為其主鍵,也可另立主鍵並將“一”和“多”兩表的主鍵作為關聯表的外來鍵;
3. 多對多的表,則必須設中間關聯表,關聯表設獨立主鍵,並引入兩個“多”頭的表的主鍵作為關聯表的外來鍵。

4. 能用1對1的,就不用1對多;能用1對多的,就不用多對多,往簡單化方向靠;
5. 能當屬性處理的,儘量當屬性,而不是當實體處理去另立新表,這樣可使問題簡化。
6.

把意義相近聯絡緊密的屬性放在一張表內,而不是拆在多張表中。

三種關係解讀
ForeignKey: 多對一
ManyToManyField:多對多
OneToOneField: 一對一
:要求第一個引數是一個模型類,需要使用verbose_name才能指定自述名。

廢話不多說,先來個簡單的模型例項:

class Category(models.Model):
    '''
    文章分類
    '''
    name = models.CharField(max_length=20,verbose_name='文章類別')
    number = models.IntegerField(default=1,verbose_name='分類數目')

class Tags(models.Model):
    '''
    文章標籤
    '''
    name = models.CharField(max_length=20,verbose_name='文章標籤')
    number = models.IntegerField(default=1, verbose_name='標籤數目')

class Blog(models.Model):
    '''
    部落格
    '''
    title = models.CharField(max_length=100,verbose_name=u'標題')
    content = models.TextField(default='',verbose_name=u'正文')
    create_time = models.DateTimeField(default=timezone.now,verbose_name=u'建立時間')
    modify_time = models.DateTimeField(auto_now=True,verbose_name=u'修改時間')
    click_nums = models.IntegerField(default=0,verbose_name=u'點選量')
    category = models.ForeignKey(Category,on_delete=models.CASCADE,verbose_name=u'文章類別')
    tags = models.ManyToManyField(Tags,verbose_name=u'文章標籤')

class Comment(models.Model):
    '''
    評論
    '''
    name = models.CharField(max_length=20,default=u'佚名',verbose_name=u'姓名')
    content = models.TextField(verbose_name=u'內容')
    create_time = models.DateTimeField(auto_now_add=True,verbose_name=u'建立時間')
    blog = models.ForeignKey(Blog,verbose_name=u'部落格')

說明:這是一個關於部落格系統的模型設計。
其中部落格與文章類別是多對一;部落格與標籤是多對多;部落格與評論是多對一;
Foreignkey:用被關聯的模型的小寫名稱做為ForeignKey欄位的名,當然你也可以取別名。
ManyToMany:用被關聯的模型的小寫名稱的複數形式做為ManyToMany欄位的名.當兩個模型都存在多對多關係,而需求是要了解更多其中的細節,那我們可以藉助*through*引數,使他轉向一箇中介模型。如下例項:

class Person(models.Model):
		name = models.CharField(max_length=128)
		class Group(models.Model):
		name = models.CharField(max_length=128)
		members = models.ManyToManyField(Person, through='Membership
')
class Membership(models.Model):
		person = models.ForeignKey(Person)
		group = models.ForeignKey(Group)
		date_joined = models.DateField()
	   invite_reason = models.CharField(max_length=64)

OneToOne::當某個物件想擴充套件自另一個物件,那可以再這個物件的主鍵上新增一對一的關係。例如:

class Place(model.Model):
		 address=models.CharField()
		phone=models.Integer()

class Restaurant(Models.model):
		place=models.OneToOneField(Plase)

說明:這裡建立了一個’Place’資料庫,裡面有一些常用的欄位,那接下來我想在已有基礎上新增’Restaurant’資料庫,而且不想將已有的欄位賦值到’Restaurant’模型中,那我們可以新增OneToOneField欄位,指向’Place’. (在這裡我們應該使用典型的繼承,它隱含了一個一對一的關係)

總結:資料庫的這三種關係就是這麼簡單,但在運用的過程中,我們需要結合具體的需求,多對
經常發生的情景是有標籤(Tags)的時;OneToOne(一對一):類似於繼承,在設計模型時,可以將多個數據路中共有的欄位集中起來,然後使用OneToOne,進行關聯。