關於django Models的個人理解和related_name的使用


  作為一個新人(剛剛大學還沒有畢業就出來實習,可以說是真的什么都不知到,什么都要重新學,但是這樣真的可以鍛煉自己的意志力和能力)。現在在公
司是前端和后端一起坐,所以要學的東西是真的多的讓人想不到。在學習的過程中也越到了不少的問題,今天和大家分享一下django中的models的一些知識,
有不對或者不當的地方希望大家可以指正,大家共同學習,共同進步,在此謝過!
  相信做程序的大家都是知道的,關系數據庫的強大不僅僅是由於用數據庫可以存放數據,更重要的是他可以存放數據庫中表與表之間的關系,Django請
提供了三種最為通用的數據庫關系模型
   1 mang-to-many(對對多關系)
   2 many-to-one(多對一關系)
  3 one-to-one(一對一關系) 
 
一,多對一關系:
  用 ForeignKey 來定義多對一的關系。用法和其他的 Field 是一樣的,把它放到模型中類的屬性定義中就行了。ForeignKey 需要一個與之相關聯的類作為

位置參數。在這里我用django book中的一個比較經典的實例來和大家一起分享一下:首先,定義了三個模型分別為:Publisher(出版商),Author(作者)和Book(書)

 1 class Publisher(models.Model):
 2     name = models.CharField(max_length=30)
 3     address = models.CharField(max_length=50)
 4     city = models.CharField(max_length=60)
 5     state_province = models.CharField(max_length=30)
 6     country = models.CharField(max_length=50)
 7     website = models.URLField()
 8     def __unicode__(self):
 9          return self.name
10 
11 
12 class Meta:
13         ordering = ['name']
14 
15 
16 class Author(models.Model):
17     first_name = models.CharField(max_length=30)
18     last_name = models.CharField(max_length=40)
19     email = models.EmailField(blank=True)
20     def __unicode__(self):
21          return  u'%s %s' % (self.first_name, self.last_name)
22 
23 
24 class Book(models.Model):
25     title = models.CharField(max_length=100)
26     authors = models.ManyToManyField(Author)
27     publisher = models.ForeignKey(Publisher, related_name = "publisher_set")
28     publication_date = models.DateField(blank=True, verbose_name='e-mail')
29     num_pages = models.IntegerField(blank=True, null=True)
30     # objects = BookManager()
31     objects = models.Manager()           # The default manager.
32     dahl_objects = DahlBookManager()     # The Dahl-specific manager
33 
34     # .
35     def __unicode__(self):
36          return self.title

要建立一個遞歸的關系,即一個對象和自身的多對一關系,你可以這樣寫:models.ForeignKey('self') :

 1 class Employee(models.Model): 2 manager = models.ForeignKey('self') 

如果你創建關系時,所需的模型還沒有被定義,你可以不使用模型對象本身,而是使用那個模型的名字。

 

1 class Car(models.Model):
2 manufacturer = models.ForeignKey('Manufacturer')
3 ...
4 class Manufacturer(models.Model):

但是,你要記住,只能對在同一個 models.py 文件中的模型使用字符串引用,對於其他應用程序中的模型或者從其他地方導入
的模型是不能使用名字對其做引用的。
Django在數據庫中使用的列名稱是對應的字段的名稱后追加 _id 得到的字符串。再前面的那個例子中, Car 模型對應的數據庫
表中會有一個名字是 manufacturer_id 的列,(你可以通過指定 db_column 來顯式改變這個名字,參見前面
的db_column一節)但是,如果你不需要寫定制的SQL語句的話,你永遠不要去處理數據庫列名,只需要處理你的模型對象中的
字段名稱。

在這里有幾個概念要講清楚,當初我就是載在這上面的,希望有同感的朋友可以看到,ForeignKey選項

1.edit_inline:

如果不設為 False 的話,它對應的對象就可以在頁面上內聯編輯,就是說這個對象有自 己獨立的
管理界面。如果設為 models.TABULAR 或者 models.STACKED 的話,這個內 聯編輯對象分別顯
示成一個表格或者一些字段的集合。

2.limit_choices_to:

可以限定對象的值的范圍的一個參數和值的字典。結合Python的 datetime 模塊的

函數可以根據日期來限定對象。例如,下面的代碼:
limit_choices_to = {'pub_date__lte': datetime.now}
把可選對象限定到 pub_date 早於當前時間的對象中。
除字典外,這里也可以是一個可以執行更復雜的查詢的 Q 對象
這個選項和 edit_inline 是不兼容的。

3.max_num_in_admin

於內聯編輯對象,這個是要在管理界面里顯示的相關對象的最多個數。所以,如果披薩最多 只會
有10種配料, max_num_in_admin=10 會保證用戶最多輸入10種配料。
記住,本項並不保證不會創建10種以上的配料,他只是控制管理界面,而不是在Python的API 層和
數據庫層做什么限制。

4.min_num_in_admin

在管理界面中要顯示的相關的對象的最少個數。通常,在創建的時候,顯示的內聯對象的個數 為
num_in_admin 個,在編輯的時候,在當前的基礎上又會多顯示 num_extra_on_change 個空對
象,但是顯示的對象個數不會少於 min_num_in_admin 個。

5.num_extra_on_change

修改對象時要額外顯示的對象數目。

6.num_in_admin

添加對象時要顯示的內聯對象的默認個數。

7.raw_id_admin

為要鍵入的整數顯示一個文本框,而不是一個下拉列表。在關聯對象有很多行時,這個比顯示 一個
列表選擇框更實用。
使用 edit_inline 時,本項無效。

8.related_name

關聯對象反向引用描述符。

9.to_field

關聯對象的用於關聯的字段,Django默認使用關聯對象的主鍵。

要學習ForeignKey並了解深刻的話,可以先對以上ForeignKey的這些選項有一定的了解。這樣可以加深你對ForeignKey的印象。

  萬事俱備,現在,假如你想通過Book這張表去訪問Publisher和Author都是可以直接訪問的,因為Book這張表中有外鍵和這兩張

表關聯,因此可以直接通過語句去訪問Book和Publisher表。

 

1 def get_info(request, id):
2     books = Book.objects.filter(publisher__id = id).all()
3     return render_to_response("showdb_info.html",{
4         "books": books
5     },
6      context_instance=RequestContext(request))

這一步相信大家都是知道的,即使不知道,等你看了筆者的這篇博客之后肯定也會一目了然的。但是,假如反過來該怎么去查詢呢?

(通過Publisher或者Author表查詢Book表中的內容)在這里就要用到一個相當重要的ForeignKey選項,通過該選項你可以隨便訪問Books

中的任意字段。

 

def get_book_info(request, id):
    publisher = Publisher.objects.filter(publisher_set__id = id)
    return render_to_response("showdb_info.html",{
        "publisher": publisher,
    },
     context_instance=RequestContext(request))

以上python函數中的都是偽代碼,有興趣的讀者可以自己設計自己的代碼。此文將會持續更新,有意者可以持續關注,歡迎大家指正不足!

 

 
 


免責聲明!

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



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