1. 程式人生 > >Django 1.11中文文件-模型(一、欄位)

Django 1.11中文文件-模型(一、欄位)

目錄:

模型Models (官方文件連結

模型是資料資訊的唯一併明確的來源。它包含了我們儲存的資料的基本欄位和行為。通常,每個模型對映到一張資料庫表。
基本概念:

  • 每個模型都是django.db.models.Model的一個子類

  • 每個屬性代表資料庫中的一個欄位

  • 在這些基礎上,Django為我們提供了一個自動生成的資料庫訪問API。

簡單示例

下面的示例模型定義了一個Person,其擁有一個first_name和一個last_name屬性。

 from django.db import models

 class Person(models.Model):
     first_name = models.CharField(max_length=30)
     last_name = models.CharField(max_length=30)

first_name和last_name是模型(model)的欄位(fields).每個欄位指定為類的一個屬性,每個屬性對映到資料庫的一列(column)。

上面的Person模型將建立類似下面這樣一個數據庫:

 CREATE TABLE myapp_person (
     "id" serial NOT NULL primary_key,
     "first_name" varchar(30) NOT NULL,
     "last_name" varchar(30) NOT NULL
 );

關於上面程式碼的一些技術註釋:

  • 上面資料表的名稱”myapp_person”,是從模型的元資料(metadata)自動匯入的,但是可以覆寫(overridden)。具體參見文件的
    Table names
    章節。
  • 這是一段運用PostgreSQL語法建立資料表的SQL語句,但我們不用為此操心,針對後臺settings file中設定好的資料庫,Django都有量身定做的SQL。

運用模型

一旦定義好模型之後,需要告訴Django我們將使用這些模型。方法是通過編輯setting.py檔案,在INSTALLED_APPS設定中新增包含了我們models.py的模組的名稱。

例如,如果我們應用程式的模型存放在myapp.models模組中(該包結構在通過manage.py startapp命令建立應用程式時形成的),INSTALLED_APP應該一部分看起來如下:

 INSTALLED_APPS = [
      #...
      'myapp',
      #...
  ] 

當新增apps到INSTALLED_APPS以後,確保要執行mangae.py migrate指令,有時候還需要先用manage.py makemigrations進行遷移。

欄位(Fields)

一個模型最重要也是唯一要求的部分,就是定義資料庫的欄位。欄位是由類的屬性指定的。注意不要選擇與模型API衝突的欄位名,如clean,save或者delete等。

示例:

  from django.db import models

  class Musician(models.Model):
      first_name = models.CharField(max_length=50)
      last_name = models.CharField(max_length=50)
      instrument = models.CharField(max_length=100)

  class Album(models.Model):
      artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
     name = models.CharField(max_length=100)
     release_date = models.DateField()
     num_stars = models.IntegerField()

欄位型別(Field types)

Each field in your model should be an instance of the appropriate Field class. Django uses the field class types to determine a few things:

模型的每一個欄位都是相應欄位類的一個例項。Django用欄位類的型別來決定一些東西:

  • 列型別(column type),告訴資料庫儲存什麼樣的資料(比如INTERGER, VARCHAR, TEXT 等)。
  • 渲染表單欄位時用預設的HTML部件(比如, 等)
  • Django的管理系統(admin)和自動生成的表單中,運用最低的驗證要求。

欄位選項(Field options)

每個欄位都有一些特定的引數(參見 model field reference),例如,CharField(及其子類)要求一個最大長度引數來規定資料庫VARCHAR欄位的大小。

也有一些每種欄位都通用的引數,都是可選的。在reference中有完整的解釋,這裡對最常用的一些做個快速的概覽:

null

如果值為True,在資料庫中Django將把空值儲存為Null。預設值為False。

blank

如果值為True,欄位允許為空。預設值為False。

注意它與null是不同的。null是純粹資料庫相關的,而blank是驗證相關的。如果一個欄位設定了blank=True, 表單驗證將允許輸入空值。如果設定了blank=False,該欄位則是必需的。

choices

一個包含了二維元組的可迭代物件(比如,列表或者元組)作為欄位的選項,預設的表單部件將從標準的文字換成選擇框,選項限定為choice引數。

chiices列表看起來像這樣:

YEAR_IN_SCHOOL_CHOICES = (
    ('FR', 'Freshman'),
    ('SO', 'Sophomore'),
    ('JR', 'Junior'),
    ('SR', 'Senior'),
    ('GR', 'Graduate'),
)

每個元組中的第一個元素是將儲存在資料庫中的值。第二個元素將通過預設的表單部件顯示,或者放在ModelChoiceField中。給出一個模型例項,可以通過get_FOO_display()方法來訪問choices field正在顯示的值。

示例:

from django.db import models

class Person(models.Model):
    SHIRT_SIZES = (
        ('S', 'Small'),
        ('M', 'Medium'),
        ('L', 'Large'),
    )
    name = models.CharField(max_length=60)
    shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
>>> p = Person(name="Fred Flintstone", shirt_size="L")
>>> p.save()
>>> p.shirt_size
'L'
>>> p.get_shirt_size_display()
'Large'

default

欄位的預設值。可以是一個值或者一個可呼叫的物件。如果是後者,每次新物件建立時都會呼叫

help_text

表單部件顯示附加的幫助資訊。如果欄位不是用在表單上,該引數對文件還是很有用的。

primary_key

如果值為True,該欄位設為模型的主鍵。

如果沒有指定任何欄位為主鍵,Django會自動新增一個IntegerField做為主鍵。所以如果不想覆寫預設的主鍵,可以不設定任何欄位的primary_key=True。

主鍵欄位是隻讀的,如果你改寫了一個原有主鍵的值然後儲存,舊物件的旁邊將會建立一個新物件。示例如下:

from django.db import models

class Fruit(models.Model):
    name = models.CharField(max_length=100, primary_key=True)
>>> fruit = Fruit.objects.create(name='Apple')
>>> fruit.name = 'Pear'
>>> fruit.save()
>>> Fruit.objects.values_list('name', flat=True)
<QuerySet ['Apple', 'Pear']>

unique

如果為True,該欄位在表中必須是唯一的。

自動主鍵欄位(Automatic primary_key fields)

id = models.AutoField(primary_key=True)

這是一個自動增長的主鍵。

如果你想指定一個自定義的主鍵,只要將某個欄位的選項設定primary_key=True。如果Django發現你已經明確了欄位的主鍵(Field.primary_key),它就不會再新增自動的id列。

每個模型要求必須有一個欄位設定為primary_key=True(明確指定的或者自動新增的都可以)。

詳細欄位名稱(Verbose field names)

除ForeignKey, ManyToManyField 和 OneToOneField以外,每種欄位都有一個第一位置引數-詳細名稱。如果該詳細名稱沒有給出,Django會自動把欄位的屬性名稱(下劃線替換成空格)作為詳細名稱。

下面這個例子,詳細名稱是”person’s first name”:

first_name = models.CharField("person's first name", max_length=30)

下面這個例子,詳細名稱是”first name”:

first_name = models.CharField(max_length=30)

ForeignKey, ManyToManyField 和 OneToOneField 要求第一位置引數為模型類,所以使用verbose_name關鍵字屬性:

poll = models.ForeignKey(
    Poll,
    on_delete=models.CASCADE,
    verbose_name="the related poll",
)
sites = models.ManyToManyField(Site, verbose_name="list of sites")
place = models.OneToOneField(
    Place,
    on_delete=models.CASCADE,
    verbose_name="related place",
)

有個慣例是不要將verbose_name的首字母大寫,Django會再需要的時候自動將其首字母大寫。

關係(Relationships)

很明顯,關係型資料庫的能力來源於相互關聯的表。Django提供了方法定義三種最常見的資料庫關係:many-to-one, many-to-many and one-to-one。

一對多關係(Many-to-one relationships)

通過django.db.models.ForeignKey來定義一對多關係。我們可以像使用其他欄位型別一樣:將其作為類屬性包含在我們的模型中。

外來鍵(ForeignKey)要求一個位置引數:該模型關聯到哪個類。

比如,一個廠家製造了很多汽車,但是每輛汽車只有一個廠家,可以如下定義:

from django.db import models

class Manufacturer(models.Model):
    # ...
    pass

class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
    # ...

建議,但沒規定,將關聯模型的小寫名稱作為外來鍵欄位的名稱(上一個示例中的manufacturer)。當然,你可以叫外來鍵欄位任何名字,比如{

class Car(models.Model):
    company_that_makes_it = models.ForeignKey(
        Manufacturer,
        on_delete=models.CASCADE,
    )
    # ...

參考資訊

外來鍵欄位接收多種其他引數,具體參見the model field reference。這些選項幫助定義關係怎麼工作,都是可選的。

多對多關係(Many-to-many relationships)

要定義一個多對多關係,用MangToManyField。

我們可以像使用其他欄位型別一樣:將其作為類屬性包含在我們的模型中。

MangToManyField要求一個位置引數:該模型關聯到哪個類。

比如,一個披薩有多種配料,一種配料也可以用在多個披薩上。可以這樣描述:

from django.db import models

class Topping(models.Model):
    # ...
    pass

class Pizza(models.Model):
    # ...
    toppings = models.ManyToManyField(Topping)

跟外來鍵一樣,你也可以建立遞迴關係以及與尚未定義的模型的關係。

建議,但未規定,用關聯模型物件的複數描述作為ManyToManyField的名稱(上面示例中的toppings)。

多對多的兩個模型中哪一個設定ManyToManyField都可以,但是隻能設定一個,不能都設定。

通常,ManyToManyField例項會通過表單填寫。在上面的示例中,tappings在Pizza中(而不是Topping有一個pizzas ManyToManyField)。因為一個有多種配料的披薩要比一種用在多個披薩上的配料要自然些。上面示例中,披薩表單中讓使用者可以選擇配料。

參考資訊

ManyToManyField接收多種其他引數,具體參見the model field reference。這些選項幫助定義關係怎麼工作,都是可選的。

多對多關係中的額外欄位(Extra fields on many-to-many relationships)

當你只需要處理簡單的多對多關係時,比如混合搭配披薩和配料,標準的多對多欄位就夠了。然而,有時候你需要兩個模型之間關係的輔助資料。

例如,設想有一種程式用來追蹤音樂家屬於哪個樂隊。人和樂隊之間是一種多對多的關係,所以我們可以用一個多對多欄位來描述該關係。然而,還有很多其他相關資訊我們也想收集,比如某人加入某個樂隊的日期。

針對這種情況,Django允許我們指定模型,用來管理該多對多關係。這樣我們可以在中間模型中設定額外的欄位。通過設定through引數來指出哪個模型作為媒介,將中間模型與多對多欄位聯合起來。我們的樂隊示例,程式碼應該差不多像這樣:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

當我們建立中間模型時,我們明確指定了到該多對多關係相關模型的外來鍵。此明確宣告定義了這兩個模型時怎麼關聯的。

中間模型中有一些約束:

  • 中間模型必須有且只有一個到源模型(我們示例中的Group)的外來鍵, 或者明確指定ManyToManyField.through_fields。如果有超過一個外來鍵而且沒有指定through_fields,會引發驗證錯誤。到目標模型(我們示例中的Person)的外來鍵也有同樣的限制。
  • 當一個模型通過中間模型到自身有多對多關係,指向同一個模型的兩個外來鍵是允許的,但是它們要按多對多關係的不同側來處理。如果存在超過兩個外來鍵,也必須跟上面一樣指定through_fields,否則會引發驗證錯誤。

現在我們已經設定好ManyToMany欄位來使用我們的中間模型(示例中的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="Needed a new drummer.")
>>> m1.save()
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>]>
>>> ringo.group_set.all()
<QuerySet [<Group: The Beatles>]>
>>> m2 = Membership.objects.create(person=paul, group=beatles,
...     date_joined=date(1960, 8, 1),
...     invite_reason="Wanted to form a band.")
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>]>

不像普通的多對多欄位,我們不可以用add(), create(), 或者 set() 去建立關係:

>>> # The following statements will not work
>>> beatles.members.add(john)
>>> beatles.members.create(name="George Harrison")
>>> beatles.members.set([john, paul, ringo, george])

為什麼?我們不能只建立人和樂隊之間的關係,我們還需要指定Membership模型要求的關係的所有資訊。簡單的add, create無法指定額外的資訊。所以,運用中間模型的多對多關係是禁用它們的。建立這種型別關係的唯一方法是建立中間模型的例項。

出於類似的原因, remove()方法也被禁用了。因為有時候remove()方法無法提供足夠的資訊來確認該刪除哪一個中間模型例項:

>>> Membership.objects.create(person=ringo, group=beatles,
...     date_joined=date(1968, 9, 4),
...     invite_reason="You've been gone for a month and we miss you.")
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>, <Person: Ringo Starr>]>
>>> # This will not work because it cannot tell which membership to remove
>>> beatles.members.remove(ringo)

然而,clear()方法可以刪除一個例項的所有多對多關係:

>>> # Beatles have broken up
>>> beatles.members.clear()
>>> # Note that this deletes the intermediate model instances
>>> Membership.objects.all()
<QuerySet []>

一旦通過建立中間模型例項建立了多對多關係,我們就可以進行查詢了。就像普通多對多關係一樣,我們可以通過相關模型的屬性進行查詢:

# Find all the groups with a member whose name starts with 'Paul'
>>> Group.objects.filter(members__name__startswith='Paul')
<QuerySet [<Group: The Beatles>]>

也可以通過中間模型的屬性進行查詢:

# Find all the members of the Beatles that joined after 1 Jan 1961
>>> Person.objects.filter(
...     group__name='The Beatles',
...     membership__date_joined__gt=date(1961,1,1))
<QuerySet [<Person: Ringo Starr]>

如果需要訪問中間模型的資訊,我們可以直接對中間模型進行查詢:

>>> ringos_membership = Membership.objects.get(group=beatles, person=ringo)
>>> ringos_membership.date_joined
datetime.date(1962, 8, 16)
>>> ringos_membership.invite_reason
'Needed a new drummer.'
>>> ringos_membership = ringo.membership_set.get(group=beatles)
>>> ringos_membership.date_joined
datetime.date(1962, 8, 16)
>>> ringos_membership.invite_reason
'Needed a new drummer.'

一對一關係(One-to-one relationships)

用OneToOneField定義一對一關係。像任何其他欄位型別一樣使用:作為屬性包含在模型中。

如果一個物件繼承自其他物件,一對一關係最適合用於它的主鍵。

OneToOneField要求一個位置引數:哪個模型是相關的。

例如,我們要建立一個關於“處所”的資料庫,可能要在資料庫中建立很多標準的東西,如地址、電話號碼等。這時,如果你還想在這些處所的基礎上再建立一個餐廳的資料庫,不必在餐廳模型中再重複指定這些欄位,只需要在餐廳模型中建立一個指向處所模型的一對一欄位。(因為一間餐廳也是一個處所。實際上,這種情況我們通常使用繼承inheritance,它是毫無疑問的一對一關係。)

跟外來鍵一樣,你也可以建立遞迴關係以及與尚未定義的模型的關係。

參考資訊

一對一欄位類以前會自動成為模型的主鍵,現在不是這樣了(儘管可以手動設定primary_key引數,如果我們想的話)。因此,現在同一個模型中可以有多個一對一欄位。

相關推薦

Django 1.11中文-模型

目錄: 模型Models (官方文件連結) 模型是資料資訊的唯一併明確的來源。它包含了我們儲存的資料的基本欄位和行為。通常,每個模型對映到一張資料庫表。 基本概念: 每個模型都是django.db.models.Model的一個子類 每個屬性

Django-1.11中文檔-模型Models

after 表數據 help var person last attr geo django 模型Models (官方文檔鏈接) 模型是數據信息的唯一並明確的來源。它包含了我們儲存的數據的基本字段和行為。通常,每個模型映射到一張數據庫表。 基本概念: 每個模型都是**dj

Django 1.10中文-聚合

正文 Django 資料庫抽象API 描述了使用Django 查詢來增刪查改單個物件的方法。 然而,有時候你要獲取的值需要根據一組物件聚合後才能得到。 這個主題指南描述瞭如何使用Django的查

Elasticsearch7.2中文翻譯:Elasticsearch簡介

為了搜尋和分析,你懂得!!! 簡介 Elasticsearch是Elastic Stack核心的分散式搜尋和分析引擎。Logstash和Beats有助於收集,聚合和豐富您的資料並將其儲存在Elasticsearch中。Kibana使您能夠以互動方式探索,視覺化和分享資料洞察,並管理和監控堆疊。Elastic

DL4J中文/模型/RNN迴圈神經網路

DL4J中的迴圈神經網路 本文概述了在DL4J中如何使用迴圈神經網路的具體訓練特徵和實用性。本文假定對迴圈神經網路及其使用有一定了解,而不是對遞迴神經網路的介紹,並且假定你對它們的使用和術語有一些熟悉。 內容 基礎:資料和網路配置 RNN訓練特徵 通過時間截

kafka 1.0 中文--Broker的配置

3.1 Broker Configs 基本配置如下:    1. broker.id    2. log.dirs    3. zookeeper.connect 下面將更詳細地討論主題級別的配置和預設設定。 名稱 描述 型別

django 1.8 官方翻譯:2-1-1 模型語法

模型 模型是你的資料的唯一的、權威的資訊源。它包含你所儲存資料的必要欄位和行為。通常,每個模型對應資料庫中唯一的一張表。 基礎: 模型的每個屬性都表示資料庫中的一個欄位。 Django 提供一套自動生成的用於資料庫訪問的API;詳見執行查詢。

Django 2.0 之Models(模型) 官方翻譯

以下翻譯是自己學習的時候順便記下的,如果有不對的地方還請指正。 模型是關於你的資料的唯一、確定的資料來源。它包含你所儲存的資料的基本欄位和行為。通常,每個模型對映到一個數據庫表。 基礎知識: 每一個模型都是一個Python類,它是 django.db.models.Mo

Django 1.10中文檔-執行查詢

pic 文檔 .cn php uid 1.10 查詢 pac .com http://pic.cnhubei.com/space.php?uid=1774&do=album&id=1360377http://pic.cnhubei.com/space.php

DL4J中文/模型/多層網路

為什麼用多層網路? MultiLayerNetwork類是Eclipse DL4J中可用的最簡單的網路配置API。該類對於不需要複雜和分支的網路圖的初學者或使用者很有用。 如果你正在建立複雜的損失函式、使用圖頂點或執行類似如三重網路的高階訓練,則不希望使用MultiLayerNetwork配

DL4J中文/模型/卷積

什麼是卷積神經網路? 神經網路配置中的每一層表示隱藏單元的單元。當層堆疊在一起時,它們代表了一個深度神經網路。 可用的層 Convolution1D (一維卷積) [原始碼] 一維卷積層。形狀期望的輸入啟用[小批量,通道,序列長度] Convolution2D(二維卷

DL4J中文/模型/計算圖

用計算圖構建複雜網路架構 本頁描述瞭如何使用 DL4J的計算圖功能來構建更復雜的網路。 內容 計算圖概述 計算圖:一些用例 配置一個計算圖網路 圖頂點型別  示例1:具有跳過連線的迴圈網路 示例2:多個輸入和合並頂點

DL4J中文/模型/自編碼器

什麼是自編碼器? 自編碼器是用於無監督學習的神經網路。Eclipse DL4J支援某些自動編碼器層,如變分自編碼器。 受限波爾滋曼機在哪? 0.9.x版本已不再支援受限波爾滋曼機了,對於多數機器學習問題它們不再是最好的選擇了。 支援的層 AutoEncoder(自編碼器)

DL4J中文/模型/自定義層

編寫自定義層 有兩個元件可新增自定義層: 新增層配置類: 擴充套件 org.deeplearning4j.nn.conf.layers.Layer 新增層實現類: 實現 org.deeplearning4j.nn.api.Layer 配置層(以上(1)

DL4J中文/模型/監聽器

什麼是監聽器? 監聽器允許使用者在Eclipse DL4J中“掛鉤”到某些事件中。這允許你收集或列印對訓練等任務有用的資訊。例如,一個ScoreIterationListener允許你從神經網路的輸出層列印訓練分數。 用法 要將一個或多個監聽器新增到一個多層網路或計算圖中,請使用addL

DL4J中文/模型/層

什麼是層? 神經網路配置中的每一層表示隱藏單元的單元。當層堆疊在一起時,它們代表了一個深度神經網路。 使用層 在Eclipse DL4J中可用的所有層都可以用在多層網路或計算圖中。當配置一個神經網路時,你傳遞層配置,網路會為你例項化該層。 層VS頂點 如果你正在配置諸如Incep

DL4J中文/模型/頂點

頂點是什麼? 在Eclipse DL4J中,頂點是在計算圖中充當節點的一種層。它可以接受多個輸入,提供多個輸出,並且可以幫助構建流行的網路,如InceptionV4。 可用的類 L2NormalizeVertex [原始碼] L2NormalizeVertex 在單個輸入上執

DL4J中文/模型/模型動物園

可用模型 AlexNet [原始碼] AlexNet Dl4J的AlexNet模型解釋基於原始論文《基於深度卷積神經網路的ImageNet分類》和引用的imagenet示例程式碼。 參考文獻: http://papers.nips.cc/paper/4824-imagen

DL4J中文/模型/迭代器

什麼是迭代器? 資料集迭代器允許將資料輕鬆載入到神經網路中,並幫助組織批處理、轉換和掩碼。包含在Eclipse DL4J中的迭代器有助於使用者提供的資料,或者自動載入公共的基準資料集如MNIST和IRIS。 用法 對於大多數用例,初始化迭代器和傳遞一個引用到MultiLayerNetwo

DL4J中文/模型/模型持久化

神經網路的儲存與載入 ModelSerializer(模型序列化器)是一個處理載入和儲存模型的類。通過連結顯示的示例中儲存模型有兩種方法。第一個例子儲存了一個正常的多層網路,第二個例子儲存了一個計算圖。 下面是一個基本示例,其中包含使用ModelSerializer類儲存計算圖的程式碼,以及