首頁 > 後端開發 > Python教學 > Django文檔-Model中的

Django文檔-Model中的

黄舟
發布: 2016-12-17 16:05:48
原創
1031 人瀏覽過

關聯關係欄位 (Relationship fields)

ForeignKey,ManyToManyField與OneToOneField分別在Model中定義多對一,多對多,一對一關係。

例如,一本書由一家出版社出版,一家出版社可以出版很多書。一本書由多位作者合寫,一個作者可以寫很多書。

class Author(models.Model):
   name=models.CharField(max_length=20)
class Publisher(models.Model):
  name=models.CharFiel Bookdmod.lengthsm(3);
   name=models.CharField(max_length=20)
   pub=models.ForeignKey(Publisher)
   authors=models.ManyToManyField(Author)
model 建立關聯,就使用model 的名稱,而不是使用model 物件本身。

例子中,如果Publisher與Author在Book後面定義,需要寫成下面的形式:

class Book(models.Model):

   name=models.CharField(max_length=20)

  集')

   authors=models.ManyToManyField('Author')


2.Model關聯自身

Model可以與自身做多對一關係

class People(models.Model): ancom =20)

   leader=models.ForeignKey('self',blank=True,null=True)

Model也可以與自身做多對多關係


class Person(models.Model):): ManyToManyField("self")

預設情況下,這種關聯關係是對稱的,如果Person1是Person2的朋友,那麼Person2也是Person1的朋友

p1=Person()

p1.save()
p2= Person()
p2.save()

p3=Person()

p3.save()

p1.friends.add(p2,p3)



上述情況下,要找p3的朋友,不用找p3.person_setp3.person_set. all(),而直接用p3.friends.all()就可以了

如果想取消這種對稱關係,將symmetrical設為False

class Person2(models.Model):
   friends=(models.ManyToyField "self",symmetrical=False)

這樣查詢p3的朋友,就需要p3.person_set.all()了

3.反向名稱related_name


反向名稱,用來從被關聯字段指向關聯關聯。 時,你必須明確指定反向名稱; 只有在你這麼做了之後, 某些特別語法 (some special syntax) 才能正常使用。

class Book(models.Model):

   name=models.CharField(max_length=20)

   pub=models.ForeignKey(Publisher,related_name='pub')

.Foreign )

這樣用Publisher或Author反向查詢Book時可以用related_name了:publisher1.pub.all()或author1.author.all()。

如果不想設定反向關係,設定related_name為'+'或以'+'結束。


user = models.ForeignKey(User, related_name='+')


如果有多個ManyToManyField指向同一個Model,這樣反向查詢FOO_set的時候就無法弄清楚是哪個ManyToManyField字段了,可以禁止反向關聯:

users = models.ManyToManyField(User, related_name='u+')

referents = models.ManyToManyField(User, related_name='ref+')

: Django 使用ForeignKey欄位名稱+ "_id" 做為資料庫中的欄位名稱。在上面的例子中,BOOK model 對應的資料表中會有 一個 publisher_id 欄位。

你可以透過明確地指定 db_column 來改變該欄位的列名稱,不過,除非你想自定 義 SQL ,否則沒必要更改資料庫的列名稱。

多對多:Django 建立一個中間表來表示ManyToManyField關係。預設情況下,中間表的名稱由兩個關係表名結合而成。

由於某些資料庫對表名的長度有限制,所以中間表的名稱會自動限制在64個字元以內,並包含一個不重複的雜湊字串。這 


意味著,你可能會看到類似 book_authors_9cdf4 這樣的表格名稱。你可以使用 db_table 選項手動指定中間表名稱。

但是,如果你想要手動指定中間表,你可以用 through 選項來指定model 使用另外某個 model 來管理多對多關係。而這個 model 就是中間表所對應的model :

class Person(models.Model):

   name = models.CharField(max_length=128)

def ):

   name = models.CharField(max_length=128)

   members = models.ManyToManyField(Person, through='Membership')

sel 含

class Group(models.Model):
   name = models.CharField(max_length=128)
   members = models.ManyToManyField(Person, self.name
class Membership (models.Model):
   person = models.ForeignKey(Person)
   group = models.ForeignKey(Group)
   date_joined = models.DateFielson()


這樣,就可以記錄某個person何時加入group了。

要建立Person與Group的關係就不能用add,create,remove了,而是需要透過Membership進行。

>>> ringo = Person.objects.create(name="Ringo Starr")

>>> paul = Person.objects.create(name="Paul McCartney")

>>> beatles = Group.objects.create (name="The Beatles")

>>> m1 = Membership(person=ringo, group=beatles,
...     date_joined=date(1962, 8, 16),
...    invite_reason= "Nummered a newdreeded .")
>>> m1.save()


clear()還是可以使用的

>>> beatles.members.clear()

當多對多關係關聯自身時,表中間的Foreign是可以指向同一個Model的,但是它們必須被看做ManyToManyField的兩邊,而不是對稱的,需要設定 symmetrical=False。

5.其它參數 (Arguments)

5.1 ForeignKey 接受下列這些可選參數,這些參數定義了關係是如何運作的。

ForeignKey.limit_choices_to

它是一個包含篩選條件和對應值的字典,用來在 Django 管理後台篩選 關聯物件。例如,利用 Python 的 datetime 模組,過濾掉不符合篩選條件關聯物件:

limit_choices_to = {'pub_date__lte': datetime.date.today}

只有 pub_date 在目前日期之前的關聯物件才允許被選取。

也可以使用 Q 物件來代替字典,從而實現更複雜的篩選。當limit_choices_to為Q物件時,如果把此外鍵欄位放在ModelAdmin的raw_id_fields時是不可用的。

ForeignKey.to_field

指定目前關係與被關聯物件中的哪個欄位關聯。預設情況下,to_field 指向被關聯物件的主鍵。

ForeignKey.on_delete

當一個model物件的ForeignKey關聯的物件被刪除時,預設此物件也會一起被級聯刪除的。

user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)

CASCADE:預設值,model物件會和ForeignKeyx一起被刪除

CASCADE:預設值,model物件會和ForeignKey ForeignKey欄位設為null。當然需要將null設為True。

SET_DEFAULT:將model物件的ForeignKey欄位設為預設值。

Protect:刪除ForeignKey關聯對

象時會產生一個ProtectedError,這樣ForeignKey關聯物件就不會被刪除了。

SET():將model物件的ForeignKey欄位設為傳遞給SET()的值。

def get_sentinel_user():

   return User.objects.get_or_create(username='deleted')[0]

class MyModel(n​​jels.Model):
getsm​​of努​​片))


DO_NOTHING:啥也不做。

5.2 ManyToManyField 接受下列可選參數,這些參數定義了關係是如何運作的。

ManyToManyField.limit_choices_to

和 ForeignKey.limit_choices_to 用法一樣。

limit_choices_to 對於透過 through 參數指定了中介表的 ManyToManyField 不起作用。

ManyToManyField.symmetrical

只要定義遞歸的多對多關係時起作用。

ManyToManyField.through

手動指定中間表

ManyToManyField.db_table

指定資料庫中保存多對多重關係資料的表名稱。如果沒有提供該選項,Django 就會根據兩個關係表的名稱產生一個新的表名,做為中間表的名稱。

6.OneToOneField

class OneToOneField(othermodel[, parent_link=False, **options])

用來定義一對一關係。籠統地講,它與聲明了 unique=True 的 ForeignKey 非常相似,不同的是使用反向關聯的時候,得到的不是一個物件列表,而是一個單獨的物件。

在某個 model 擴展自另一個 model 時,這個字段是非常有用的;例如: 多表繼承 (Multi-tableinheritance) 就是透過在子 model 中加入一個指向父 model 的一對一關聯而實現的。

必須給予該欄位一個參數:被關聯的 model 類別。運作方式和 ForeignKey 一樣,連遞迴關聯 (recursive) 和 延遲關聯 (lazy) 都一樣。

此外,OneToOneField 接受 ForeignKey 可接受的參數,只有一個參數是 OnetoOneField 專有的:OneToOneField.parent_link

如果為 True ,且作用於繼承自某個父 model 的子 model 上(這裡不能是延後繼承,父 model 必須真實存在 ),那麼該字段就會變成指向父類實例的引用(或者叫鏈接),

而不是像其他OneToOneField 那樣用於擴展父類並繼承父類屬性。

from django.db import models, transaction, IntegrityError

class Place(models.Model):
   name = models.CharField(max_length=50)
m o.   def __unicode__(self ):
       return u"%s the place" % self.name

class Restaurant(models.Model):
   place = models.OneToOneField(Placedog primrimy) primary_r.
   serves_pizza = models .BooleanField()

   def __unicode__(self):
       return u"%s the restaurant" % self.place.name

class WlterKey(Fall) Wl​​met(
   name = models 。不是物件列表,而是單獨的物件:

>>> p1 = Place(name='Demon Dogs', address='944 W. Fullerton')
>>> p1.save()
>>> r = Restaurant(place=p1, serves_hot_dogs=True, serves_pizza=False)
>>> r.save()

>>> p1.restaurant


>> (restaurant__place__name__startswith="Demon")

>>> Waiter.objects.filter(restaurant__place__name__startswith="Demon")

文章請關注PHP中文網(www.php.cn) !



相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板