Django之模型繼承

  • Django 的所有基類都必須是django.db.models.Model的子類
  • Djang 共有三種繼承方式:
    (1) 抽象基類:基類不會(huì)被單獨(dú)使用(模型不會(huì)用于創(chuàng)建任何數(shù)據(jù)庫(kù)表),用于保存子模型的一些公共信息
    (2) 多表繼承:子類化一個(gè)現(xiàn)有模型(可能完全來(lái)自另一個(gè)應(yīng)用程序),但每個(gè)模型都有自己的數(shù)據(jù)庫(kù)表
    (3) 代理模型:僅修改模型的Python級(jí)行為,而不以任何方式更改模型字段

抽象基類

??抽象基類聲明:像普通模型一樣聲明,但需要在Meta類中設(shè)置abstract=True

from django.db import models

class CommonInfo(models.Model):
    name = models.CharField(max_length=100)
    age = models.PositiveIntegerField()
    # 聲明抽象基類
    class Meta:
        abstract = True

class Student(CommonInfo):
    home_group = models.CharField(max_length=5)

??當(dāng)進(jìn)行數(shù)據(jù)庫(kù)遷移的時(shí)候,由于CommonInfo類聲明是抽象基類,所以不會(huì)生成數(shù)據(jù)庫(kù)表或具有管理器,并且無(wú)法直接實(shí)例化或保存。
??由于 Student 類繼承 CommonInfo 類,所以 Student 生成的數(shù)據(jù)庫(kù)為Student(name, age, home_group )

Meta 繼承
  • 當(dāng)使用抽象基類時(shí),如果子類沒(méi)有聲明它自己的Meta類,它將繼承父類的Meta。
  • 如果子類想要擴(kuò)展父類的Meta類,可以將其子類化。
  • 當(dāng)子類繼承父類Meta時(shí),會(huì)自動(dòng)設(shè)置abstract=False,即抽象基類的子項(xiàng)本身不會(huì)自動(dòng)成為抽象類,如果想聲明抽象基類,必須在自己的Meta中聲明abstract=True
from django.db import models

class CommonInfo(models.Model):
    name = models.CharField(max_length=100)
    age = models.PositiveIntegerField()
    # 聲明抽象基類
    class Meta:
        abstract = True
        ordering = ['name']

class Student(CommonInfo):
    home_group = models.CharField(max_length=5)
    # 繼承CommonInfo類的Meta
    class Meta(CommonInfo.Meta):
        db_table = 'student_info'
  • 在抽象基類Meta類中包含一些屬性是無(wú)意義的,比如說(shuō)如果在抽象基類中包含db_table則意味著所有子類將使用相同的數(shù)據(jù)庫(kù)表

多表繼承

??每個(gè)模型對(duì)應(yīng)于自己的數(shù)據(jù)庫(kù)表,可以單獨(dú)查詢和創(chuàng)建。多表繼承使得子模型與父模型之間創(chuàng)建一對(duì)一關(guān)系OneToOneField

from django.db import models

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

class Restaurant(Place):
    serves_hot_dogs = models.BooleanField(default=False)
    serves_pizza = models.BooleanField(default=False)

其中Restaurant類等價(jià)于

class Restaurant(models.Model):
    place_ptr = models.OneToOneField(
        Place, 
        on_delete=models.CASCADE,
        parent_link=True,
    )
    serves_hot_dogs = models.BooleanField(default=False)
    serves_pizza = models.BooleanField(default=False)
Meta與多表繼承
  • 一般情況下,子類無(wú)法繼承父類Meta
  • 在少數(shù)有限的情況下,子類從父類繼承行為:如果子類沒(méi)有指定ordering屬性或get_latest_by屬性,那么它將從父元素繼承這些屬性。
  • 如果父級(jí)有一個(gè)排序,并且您不希望子級(jí)具有該排序,則可以使用如ordering = []明確禁用父類屬性

代理模型

  • 作用:為原始模型創(chuàng)建代理。代理可以創(chuàng)建、刪除和更新代理模型的實(shí)例,所有數(shù)據(jù)都將像使用原始(非代理)模型一樣保存。不同之處在于,代理可以更改諸如代理中的默認(rèn)模型排序或默認(rèn)管理器之類的內(nèi)容,而無(wú)需更改原始的排序。
  • 代理模型聲明:像普通模型一樣聲明,但需要在Meta類中設(shè)置proxy=True
from django.db import models

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

class MyPerson(Person):
    class Meta:
        proxy = True

    def do_something(self):
        # ...
        pass
  • 代理的意義:僅修改模型的Python級(jí)行為,而不以任何方式更改模型字段
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 文章內(nèi)容大部分參考官方文檔,以作者理解敘述Django中模型是你的數(shù)據(jù)的唯一的,確定的信息源.它包含你所存儲(chǔ)數(shù)據(jù)所...
    da_yu閱讀 2,131評(píng)論 0 3
  • Django 模型定義 Django 模型是使用 Python 代碼對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的描述,是數(shù)據(jù)的結(jié)構(gòu),包含數(shù)據(jù)的...
    Am3閱讀 1,408評(píng)論 0 2
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,665評(píng)論 1 32
  • 著名詩(shī)人海子有言 “青海湖上,我的孤獨(dú)如天堂的馬匹” 因此我記住了青海湖 倉(cāng)央嘉措有詩(shī) “納木措湖等了我多少年,我...
    旅行懶懶閱讀 774評(píng)論 0 1

友情鏈接更多精彩內(nèi)容