[英]What is related_name used for?
什么是related_name
上有用的參數ManyToManyField
和ForeignKey
領域? 例如,給定以下代碼, related_name='maps'
的作用是什么?
class Map(db.Model):
members = models.ManyToManyField(User, related_name='maps',
verbose_name=_('members'))
related_name
屬性指定從User
模型返回到您的模型的反向關系的名稱。
如果您沒有指定related_name
,Django 會使用您的模型名稱和后綴_set
自動創建一個,例如User.map_set.all()
。
如果您確實指定了,例如, User
模型上的User.map_set
related_name=maps
, User.map_set
仍然有效,但User.maps.
語法顯然更簡潔,不那么笨重; 例如,如果您有一個用戶對象current_user
,您可以使用current_user.maps.all()
來獲取與current_user
有關系的Map
模型的所有實例。
Django 文檔有更多細節。
要添加到現有答案 - 相關名稱是必須的,以防模型中有 2 個 FK 指向同一個表。 例如在材料清單的情況下
@with_author
class BOM(models.Model):
name = models.CharField(max_length=200,null=True, blank=True)
description = models.TextField(null=True, blank=True)
tomaterial = models.ForeignKey(Material, related_name = 'tomaterial')
frommaterial = models.ForeignKey(Material, related_name = 'frommaterial')
creation_time = models.DateTimeField(auto_now_add=True, blank=True)
quantity = models.DecimalField(max_digits=19, decimal_places=10)
因此,當您必須訪問此數據時,您只能使用相關名稱
bom = material.tomaterial.all().order_by('-creation_time')
否則它不起作用(至少在 2 個 FK 到同一個表的情況下,我無法跳過相關名稱的使用。)
如果您有更復雜的相關類名, related_name
參數也很有用。 例如,如果您有外鍵關系:
class UserMapDataFrame(models.Model):
user = models.ForeignKey(User)
為了從相關的User
訪問UserMapDataFrame
對象,默認調用將是User.usermapdataframe_set.all()
,它很難閱讀。
使用related_name
允許您指定一個更簡單或更清晰的名稱來獲得反向關系。 在這種情況下,如果您指定user = models.ForeignKey(User, related_name='map_data')
,則調用將為User.map_data.all()
。
你的問題的要點如下。
由於您有Map
和User
模型,並且您已經在 Map 模型中定義了ManyToManyField
,如果您想訪問 Map 的成員,那么您可以選擇map_instance.members.all()
因為您已經定義了members字段。 但是,假設您要訪問用戶所屬的所有地圖,那么您有什么選擇。
默認情況下,Django會為您提供user_instance.modelname_set.all()
這將轉換為user.map_set.all()
在這種情況下。
地圖比map_set 好得多。
related_name為您提供了一種能力,讓 Django 知道您將如何從 User 模型訪問 Map 或者通常如何訪問反向模型,這是創建 ManyToMany 字段和在這種意義上使用 ORM 的重點。
相關的名稱參數實際上是一個選項。 如果我們不設置它,Django 會自動為我們創建關系的另一端。 在 Map 模型的情況下,Django 會創建一個map_set
屬性,允許通過您的示例中的m.map_set
進行訪問(m 是您的類實例)。 Django 使用的公式是模型名稱后跟字符串_set
。 因此,相關的 name 參數只是覆蓋了 Django 的默認值,而不是提供新的行為。
prefetch_related
用於多對多和多對一關系數據的預取數據。 select_related
是從單值關系中選擇數據。 這兩者都用於從模型的關系中獲取數據。 例如,您構建一個模型和一個與其他模型有關系的模型。 當請求到來時,您還將查詢他們的關系數據,Django 有很好的機制來訪問他們關系中的數據,例如book.author.name
但是當您迭代模型列表以獲取他們的關系數據時,Django 為每個請求創建每個請求關系數據。 為了克服這個問題,我們確實有prefetchd_related
和selected_related
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.