最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Django OneToOneField和ForeignKey的區(qū)別詳解

 更新時(shí)間:2020年03月30日 09:34:20   作者:GrandG7  
這篇文章主要介紹了基于Django OneToOneField和ForeignKey的區(qū)別詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧

根據(jù)Django官方文檔介紹:

A one-to-one relationship. Conceptually, this is similar to a ForeignKey with unique=True, but the “reverse” side of the relation will directly return a single object.

OneToOneField與ForeignKey加上unique=True效果基本一樣,但是用OneToOneField反向關(guān)聯(lián)會(huì)直接返回對(duì)象。

相反地,使用ForeignKey, 反向關(guān)聯(lián)后會(huì)返回QuerySet。

例子:

from django.db import models

class Engine(models.Model):
 name = models.CharField(max_length=25)

 def __unicode__(self):
 return self.name

class Car(models.Model):
 name = models.CharField(max_length=25)
 engine = models.OneToOneField(Engine)

 def __unicode__(self):
 return self.name

class Engine2(models.Model):
 name = models.CharField(max_length=25)

 def __unicode__(self):
 return self.name

class Car2(models.Model):
 name = models.CharField(max_length=25)
 engine = models.ForeignKey(Engine2, unique=True)

 def __unicode__(self):
 return self.name

在python manage.py shell里輸入:

>>> from testapp.models import Car, Engine
>>> c = Car.objects.get(name='Audi')
>>> e = Engine.objects.get(name='Diesel')
>>> e.car # OneToOneField的反向關(guān)聯(lián)屬性如果沒有寫relate_name, 則是對(duì)方類名的小寫
<Car: Audi>
>>> from testapp.models import Car2, Engine2
>>> c2 = Car2.objects.get(name='Mazda')
>>> e2 = Engine2.objects.get(name='Wankel')
>>> e2.car2_set.all() # OneToOneField的反向關(guān)聯(lián)屬性如果沒有寫relate_name, 則是對(duì)方類名的小寫_set
[<Car2: Mazda>]

補(bǔ)充知識(shí):Django ForeignKey,ManyToManyField和OneToOneField的辨析

導(dǎo)引

模型(Models)是對(duì)網(wǎng)站所需信息種類的定義,其包含了網(wǎng)站存儲(chǔ)數(shù)據(jù)中的重要字段和數(shù)據(jù)行為。一般來說,一個(gè)模型對(duì)于數(shù)據(jù)庫中的一個(gè)表單。

字段(Fields)是模型的重要和唯一組成部分,他們由類別的屬性值所指定。

Field分類

由官方文檔Model field reference | Django Documentation定義:

Field一共分為AutoField、BinaryField、BooleanField、CharField、DateField、DecimalField、EmailField、FileField、FloatField、IntegerField、TextField、TimeField、URLField等類別,豐富的類別選項(xiàng)為數(shù)據(jù)庫存儲(chǔ)方式提供了完善的支持,而本文主要是針對(duì)如下三個(gè)關(guān)系型字段(Relationship fields):

關(guān)系型字段 對(duì)應(yīng)關(guān)系
ForeignKey 多對(duì)一
ManyToManyField 多對(duì)多
OneToOneField 一對(duì)一

分析

ForeignKey

首先查看源碼,在類的開頭有如下參數(shù):

many_to_many = False
many_to_one = True
one_to_many = False
one_to_one = False

由此可見,F(xiàn)oreignKey是many_to_one類型的,即“一對(duì)多”,我們引用官方文檔給出的示例:

from django.db import models

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

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

由此我們可以看到,Car類型中有manufacturer字段,其類型是對(duì)應(yīng)Manufacturer類的ForeignKey。我們可以根據(jù)生活常識(shí)理解這種定義,由于一部汽車對(duì)應(yīng)一個(gè)生產(chǎn)商,而一個(gè)生產(chǎn)商可以對(duì)應(yīng)許多部汽車,所以兩者具有“一對(duì)多”的關(guān)系,在此種情況我們使用ForeignKey。

對(duì)于每個(gè)ForeignKey,我們需要給出關(guān)聯(lián)的模型和on_delete響應(yīng)的選項(xiàng),即

 manufacturer = models.ForeignKey(
 'Manufacturer',
 on_delete=models.CASCADE,
 )

on_delete函數(shù)的作用是在此字段被刪除的時(shí)候做出的響應(yīng),其可選項(xiàng)如下:

選項(xiàng) 功能
CASCADE 級(jí)聯(lián)刪除,此類選項(xiàng)模仿SQL語句ON DELETE CASCADE,再刪除此字段信息的時(shí)候同時(shí)刪除包含F(xiàn)oreignKey字段的目標(biāo)(object)
PROTECT 通過django.db.IntegrityError中的ProtectedError來保護(hù)此字段不被刪除,若進(jìn)行刪除操作則拋出錯(cuò)誤
SET_NULL 將ForeignKey置為空,這只在null選項(xiàng)為True的時(shí)候產(chǎn)生作用
SET_DEFAULT 設(shè)為默認(rèn)值(default value),此默認(rèn)值已預(yù)先對(duì)ForeignKey設(shè)置
SET() 對(duì)ForeignKey設(shè)置對(duì)SET()函數(shù)傳遞的數(shù)值
DO_NOTHING 不進(jìn)行任何操作。若數(shù)據(jù)庫提高了引用完整性,則此種設(shè)置會(huì)拋出一個(gè)IntegrityError,除非對(duì)這一數(shù)據(jù)字段手動(dòng)添加了SQL語句中的ON DELETE字段

還可以通過設(shè)置abstract屬性來定義一個(gè)抽象類:

from django.db import models

class AbstractCar(models.Model):
 manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)

 class Meta:
 abstract = True

ForeignKey還有如下的參數(shù)可以選擇:

參數(shù) 功能
limit_choices_to 通過一個(gè)限制對(duì)字段信息的某一可能選項(xiàng)進(jìn)行約束,可以通過字典,函數(shù)或者查詢值來設(shè)置
related_name 可以指定關(guān)聯(lián)的類在本類中的名稱,通過這一參數(shù)可以用兩個(gè)字段名引用同一個(gè)類,通過這個(gè)名稱父類可以取得子類的值,默認(rèn)為字段名
related_query_name 用于filter函數(shù)過濾和values函數(shù)
to_field 關(guān)系關(guān)聯(lián)的相關(guān)對(duì)象名稱
db_constraint 控制在數(shù)據(jù)庫中是否應(yīng)該建立這一字段的約束
swappable 用于控制這一字段對(duì)于可交換類模型的行為

ManyToManyField

同樣在源碼中我們可以找到針對(duì)ManyToManyField的如下定義:

many_to_many = True
many_to_one = False
one_to_many = False
one_to_one = False

由此可以知道,ManyToManyField是針對(duì)“many-to-many”即多對(duì)多關(guān)系定義的,它需要知道它關(guān)聯(lián)的類別。

官方文檔給出的示例代碼可以幫助理解:

from django.db import models

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

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

在示例代碼中,Pizza類的toppings字段由ManyToManyField與Toppings關(guān)聯(lián),我們可以由生活常識(shí)得出一片披薩上面會(huì)有很多種類的佐料,而一種佐料又可以用來制作多種披薩,兩者滿足“多對(duì)多”的關(guān)系。

ManyToManyField類有兩個(gè)經(jīng)常使用的參數(shù):through和through_fields,通過這兩個(gè)參數(shù)可以十分方便地建立中間項(xiàng)的關(guān)聯(lián),如示例代碼所示:

from django.db import models

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

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

class Membership(models.Model):
 group = models.ForeignKey(Group, on_delete=models.CASCADE)
 person = models.ForeignKey(Person, on_delete=models.CASCADE)
 inviter = models.ForeignKey(
 Person,
 on_delete=models.CASCADE,
 related_name="membership_invites",
 )
 invite_reason = models.CharField(max_length=64)

在Group類中有ManyToManyField類的字段members,這一字段通過through參數(shù)與membership聯(lián)系起來,后者表示“成員資格”,即表示“團(tuán)體”與“個(gè)人”之間關(guān)系的中間項(xiàng),而“through_fields”字段即為中間項(xiàng)連接起來的兩個(gè)類名,此處即group和person兩個(gè)類。

ManyToManyField還有以下參數(shù)可以選擇:

參數(shù) 功能
related_name 同F(xiàn)oreignKey,可以指定關(guān)聯(lián)的類在本類中的名稱
related_query_name 同F(xiàn)oreignKey,應(yīng)用于filter和values函數(shù)
limit_choices_to 同F(xiàn)oreignKey,但如果自己定義了如“Membership”之類的中間類,則不會(huì)起到作用
symmetrical 對(duì)于迭代定義的ManyToManyField,其為這一字段建立一個(gè)單獨(dú)的屬性,而是設(shè)定symmetrical屬性為True,若期望使用此類迭代關(guān)系,可以手動(dòng)設(shè)置其為False
through 如上所示,用于設(shè)置中間項(xiàng)的名字,可以自己定義一個(gè)中間項(xiàng),若不定義的話系統(tǒng)也會(huì)分配一個(gè)中間項(xiàng)
through_fields 通過元組來給出中間項(xiàng)關(guān)聯(lián)的兩個(gè)類名,可以查看上面的示例
db_table 可以通過這一屬性來手動(dòng)設(shè)定保存這一字段的數(shù)據(jù)表名稱,若不設(shè)置則默認(rèn)為字段的名稱
db_contraint 是否在數(shù)據(jù)庫中建立約束
swappable 設(shè)置是否指向一個(gè)可交換的模型

OneToOneField

源碼中對(duì)OneToOneField的設(shè)置如下:

many_to_many = False
many_to_one = False
one_to_many = False
one_to_one = True

可知其是針對(duì)單對(duì)單的關(guān)系設(shè)定的字段。在概念上我們可以理解其為設(shè)置unique屬性為True的一種類型,區(qū)別之處在于它“反向”的數(shù)值會(huì)返回一個(gè)目標(biāo)值,這對(duì)于繼承關(guān)系的表達(dá)十分有用,例如一下示例程序:

from django.conf import settings
from django.db import models

class MySpecialUser(models.Model):
 user = models.OneToOneField(
 settings.AUTH_USER_MODEL,
 on_delete=models.CASCADE,
 )
 supervisor = models.OneToOneField(
 settings.AUTH_USER_MODEL,
 on_delete=models.CASCADE,
 related_name='supervisor_of',
 )

OneToOneField既包含F(xiàn)oreignKey中的參數(shù),又包含一個(gè)額外的參數(shù)parent_link,若定義了一個(gè)類,其繼承了一個(gè)非抽象的類,而設(shè)置parent_link這個(gè)函數(shù)為True,則會(huì)將這個(gè)類視作繼承的類的父類,而不是一個(gè)新的OneToOneField。

以上這篇基于Django OneToOneField和ForeignKey的區(qū)別詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • python daemon守護(hù)進(jìn)程實(shí)現(xiàn)

    python daemon守護(hù)進(jìn)程實(shí)現(xiàn)

    這篇文章主要介紹了python daemon守護(hù)進(jìn)程實(shí)現(xiàn),需要的朋友可以參考下
    2016-08-08
  • Python中Word文件自動(dòng)化操作小結(jié)

    Python中Word文件自動(dòng)化操作小結(jié)

    Python-docx是一個(gè)Python庫,提供了對(duì)Microsoft?Word(.docx文件)的讀寫和修改功能,本文主要介紹了如何使用Python-docx實(shí)現(xiàn)Word文件自動(dòng)化操作,需要的可以參考下
    2024-04-04
  • Python 實(shí)現(xiàn)文件讀寫、坐標(biāo)尋址、查找替換功能

    Python 實(shí)現(xiàn)文件讀寫、坐標(biāo)尋址、查找替換功能

    這篇文章主要介紹了Python 實(shí)現(xiàn)文件讀寫、坐標(biāo)尋址、查找替換功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2019-09-09
  • numpy中np.c_和np.r_的用法解析

    numpy中np.c_和np.r_的用法解析

    本文主要介紹了numpy中np.c_和np.r_的用法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • tensorflow 自定義損失函數(shù)示例代碼

    tensorflow 自定義損失函數(shù)示例代碼

    這篇文章主要介紹了tensorflow 自定義損失函數(shù)示例,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • 基于python實(shí)現(xiàn)坦克大戰(zhàn)游戲

    基于python實(shí)現(xiàn)坦克大戰(zhàn)游戲

    這篇文章主要為大家詳細(xì)介紹了基于python實(shí)現(xiàn)坦克大戰(zhàn)游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • Python 中的Schema數(shù)據(jù)結(jié)構(gòu)及類型校驗(yàn)詳解

    Python 中的Schema數(shù)據(jù)結(jié)構(gòu)及類型校驗(yàn)詳解

    schema?是一個(gè)簡(jiǎn)單而強(qiáng)大的庫,用于定義和驗(yàn)證 Python 數(shù)據(jù)結(jié)構(gòu)的約束,使用?schema?庫來執(zhí)行數(shù)據(jù)結(jié)構(gòu)的校驗(yàn),本文給大家介紹Python 中的Schema數(shù)據(jù)結(jié)構(gòu)及類型校驗(yàn),感興趣的朋友一起看看吧
    2023-11-11
  • django中related_name的用法說明

    django中related_name的用法說明

    這篇文章主要介紹了django中related_name的用法說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • Python?查找算法之二分查找線性查找與哈希查找實(shí)例探究

    Python?查找算法之二分查找線性查找與哈希查找實(shí)例探究

    這篇文章主要為大家介紹了Python查找算法探究之二分查找、線性查找與哈希查找的實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Python 使用openpyxl處理Excel文件詳情

    Python 使用openpyxl處理Excel文件詳情

    這篇文章主要介紹了Python 使用openpyxl處理Excel文件詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08

最新評(píng)論

洪洞县| 土默特左旗| 资溪县| 喀什市| 瓮安县| 石棉县| 塔城市| 弥勒县| 视频| 体育| 西平县| 永安市| 翼城县| 叶城县| 定陶县| 泗阳县| 城固县| 娄底市| 逊克县| 汨罗市| 弋阳县| 七台河市| 鹿泉市| 灵丘县| 遵义县| 湟中县| 万源市| 阳高县| 鄂托克前旗| 海盐县| 聂荣县| 阿图什市| 象山县| 岳阳县| 应城市| 南投市| 呼玛县| 漳平市| 兴山县| 仁怀市| 宁化县|