程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Django 模型繼承以及 model related_name 使用

編輯:Python

背景知識

最近開發的一個項目中用到模型快照剛開始准備用 Django 模型做,於是查看了 Django 模型繼承的幾種方式,由於該項目只是使用 Django 作為後台管理並沒有直接生成遷移文件定義數據庫。最後這些模型繼承方案都未被采用但是這裡還是需要總結記錄。

Django 模型繼承的三種方式

抽象繼承

抽象繼承:創建一個通用的父類,但是我們並不想父類被創建,但是繼承該父類的子類都有該抽象父類的字段。在抽象父類的 Meta 中設置 abstract=true 即可實現。

應用場景舉例:

我們有兩個模型 Book 、Author 這兩個模型我們都需要 createdAt 以及 updatedAt 以及 enable 字段,如果我們每個模型都定義一次這樣會顯得有點冗余,這裡可以采用抽象模型繼承的方式,我們定義一個父類包含 createdAt 以及 updatedAt 以及 enable 字段 Book、Author 這兩個類去繼承該父類即可

from django.db import models
# 定義父類抽象類
class Base(models.Molde):
createdAt = models.BigIntegerField(verbose_name='創建時間')
updatedAt = models.BigIntegerField(verbose_name='更新時間')
enable = models.BooleanField(verbose_name='是否可用')
class Meta:
# 表示該模型為抽象類不會被創建
abstract = True
# 定義子類, 子類中包含父類中的所有屬性以及自身所定義的屬性
class Book(Base):
name = models.CharField(max_length=32)
class Author(Base):
name = models.CharField(max_length=32)

多表繼承

對於多表繼承其父類也是一個 Django 模型,並且父類會創建一個數據表,多表繼承是 Djnago 中一種隱式的一對一的關系:

# 父類
class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
# 子類 
class Restaurant(Place):
serves_hot_dogs = models.BooleanField()
serves_pizza = models.BooleanField()

這裡 Restaurant 和 Place 是一對一的關系,當我們在執行 django 生成遷移文件命令時可以看到他們之間的關系。

注意️:使用多表繼承時父類子類必須是使用 django 遷移生成的表,否則無法正常使用表模型

proxy model(代理model)

使用代理模式的模型表不會被創建,其實都是指向同一個模型。

from django.db import models
class Person(models.Model):
id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=32)
class OrderPerson(Person):
class Meta:
ordering = ['id']
proxy = True

這裡的 OrderPerson 並不會被創建,當我們在修改 OrderPerson 中的數據時對應的 Person 中的數據也會被修改。

注意️:proxy model 不能繼承抽象類,這是因為代理 model 是操作鏈接數據庫的也不能多重繼承,如果你使用了多重繼承 proxy model 就不知道去找那個父親類。

Django. model 中 related_name 使用

假設我們有如下兩個模型 Book、Author

class Author(models.Model):
id = models.BigAutiField(primary_key=True)
name = models.CharField(max_length=32)
class Book(models.Models):
name = models.CharField(max_lenght=32)
first_author = models.ForeignKey(Author, no_delete=models.CASCADE)
secend_author = models.ForeignKey(Author, no_delete=models.CASCADE)

如上模型定義我們的書籍可能有多個作者,first_author secend_author 都關聯 Author 這張表,如果我們運行該代碼會被錯。

原因:指向一個模型的兩個外鍵反向關聯名稱產生沖突,django 默認情況下對每個主表的對象都有一個外鍵屬性,可以通過它查詢到所有關於子表的信息,這個屬性的名字默認就是子表的名稱小寫加上_set,而 first_author 和 secend_author 該屬性默認都是 book_set,導致沖突,解決辦法:我們可以通過定義 related_name 來手動定義該屬性,正確代碼如下:

class Author(models.Model):
id = models.BigAutiField(primary_key=True)
name = models.CharField(max_length=32)
class Book(models.Models):
name = models.CharField(max_lenght=32)
first_author = models.ForeignKey(Author, no_delete=models.CASCADE, related_name='first_author')
secend_author = models.ForeignKey(Author, no_delete=models.CASCADE, related_name='secend_author')

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved