1. 程式人生 > >多對多表的構建 管理頁面屬性 外來鍵查詢

多對多表的構建 管理頁面屬性 外來鍵查詢

多對多表的構建

管理頁面屬性

外來鍵查詢

這裡對Many-To-Many即多對多的對映關係以詳細事例來分析Django中Database操作多對多對映關係的一些基本用法和注意事項

首先Many-To-Many關係在資料庫設計中經常會遇到,譬如說排課系統中的教師和教室 的關係就是最典型的例子,一名教師可以對應多個教室(該教師有多門課程),反過來說,一個教室可以對應多名教師(該教室一天有很多門課)。我們自己在設計的時候一般會是這樣的想法,假設一張表作為教師表,一張表作為教室表,為了維護兩張表之間的關係,我們會再設計第三章表,教師-教室關聯表,而此表一般只用做兩張表關聯查詢使用,所以一般會是三個column,第一個field是自增的主鍵,其餘兩個field一般就是引用兩張表的外來鍵。正式基於此,Django將這種一般話的行為封裝起來,方便大家使用。

下面我們引用Publication和Article之間的多對多的關係進行舉例分析Django中的用法。

首先我們在Django中新建一個app,命名sblog,然後models.py中新增對應的class,

class Publication(models.Model):
    title=models.CharField(max_length=30)
 
    def __str__(self):
        return self.title
 
    class Meta:
        ordering=('title',)
 
class Article(models.Model):
    headline=models.CharField(max_length=100)
    publications=models.ManyToManyField(Publication)
 
    def __str__(self):
        return self.headline
 
    class Meta:
        ordering=('headline',)

這裡我們在article中顯示的使用了ManyToManyField來宣告publications ,至此我們構建了一個最簡單的多對多關係的對映,接下來我們使用python manage.py validate來驗證我們設計的class沒有任何問題,
0 errors found

然後我們需要將設計好的model中在mysql中生效,我們使用python manage.py syncdb來應用到mysql資料庫中

Creating tables ...
Creating table sblog_publication
Creating table sblog_article_publications
Creating table sblog_article
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)

這裡發現Django幫我們做的封裝,建立了三張表,其中sblog_article_publications是Django幫我們建立的,我們不妨開啟我們的mysql,看看錶結構
使用describe sblog_article_publications命令

Field Type Null Key Default Extra
id int(11) NO PRI NULL auto_increment
article_id int(11) NO MUL NULL
publication_id int(11) NO MUL NULL

到這裡Django幫我們把表的底層結構設計好了,接下來我們就需要使用Django提供的介面來進行多對多關係對映的資料庫的基本操作

首先我們準備一些測試資料:

新增幾個publication:

>>> p1 = Publication(title='The Python Journal')
>>> p1.save()
>>> p2 = Publication(title='Science News')
>>> p2.save()
>>> p3 = Publication(title='Science Weekly')
>>> p3.save()

呼叫save方法將最基本的Publication物件提交至資料庫中,接下來需要做的就是建立一個Article物件,

>>> a1=Article(headline='Django lets you build  Web apps easily')
>>> a1.save()

之後我們便可以在a1物件上進行Publish的添加了,

>>> a1.publications.add(p1)
>>> a2=Article(headline='NASA uses Python')
>>> a2.save()
>>> a2.publications.add(p1,p2)
>>> a2.publications.add(p3)
>>> new_publication=a2.publications.create(title='Highlights for Children')

我們新增Publish物件至Article中變得十分的方便,每次新增其實質是呼叫了資料庫的批量操作,因此在效率上也比普通的add語句執行快,我們不妨檢視一下我們新增後的結果

>>> a1.publications.all()
[<Publication: The Python Journal>]
>>> a2.publications.all()
[<Publication: Highlights for Children>, <Publication: Science News>, <Publication: Science Weekly>, <Publication: The Python Journal>]

這裡我們直接使用在class中顯示宣告 的多對多的publication屬性就可以方便的查詢到所有和某一個articel相關的Publication物件,可能有人會問既然是多對多關係,剛才我們這種查詢屬於正序查詢,那可否到過來查詢呢?當然,Django也想到了,因此提供了反向查詢的方法:

>>> p2.article_set.all()
[<Article: NASA uses Python>]

這裡article_set就是提供反向查詢的預設屬性,是不是似曾相識呢?在Hibernate中雙向對映關係也使用了xxxxset關鍵字作為反向查詢入口。
其餘操作資料庫的操作如field ,get,delete,update在上面基於查詢的結果集QuerySet上進行相應的操作,詳細可參考Django文件。