Django model 反向引用中的related_name
問題:
定義表Apple:
class Apple( models.Model):
origin_level = models.ForeignKey(AppleLevel)
new_level = models.ForeignKey(AppleLevel)
出現如下問題:
monitor.apple: Accessor for field ‘origin_level’ clashes with related field ‘AppleLevel.apple_set’. Add a related_name argument to the definition for ‘origin_level’.
monitor.apple: Accessor for field ‘new_level’ clashes with related field ‘AppleLevel.apple_set’. Add a related_name argument to the definition for ‘new_level’.
原因:
一個數據表同時兩次外鍵引用另一個表,出現重名問題。
解決辦法:
使用related_name屬性定義名稱(related_name是關聯對象反向引用描述符)。
具體修改代碼如下:
class Apple( models.Model):
origin_level = models.ForeignKey(AppleLevel, related_name='orgin_level_appleset')
new_level = models.ForeignKey(AppleLevel, related_name='new_level_appleset')
related_name使用之后,有什么用處呢?
用處就是:
通過AppleLevel可以得到引用自身的Apple對象。
例如,
通過origin_level引用AppleLevel 中id為12的Apple的所有對象
AppleLevel.object.get(id=12).origin_level_appleset.objects.all()
通過new_level引用AppleLevel 中id為12的Apple的所有對象
AppleLevel.object.get(id=12).new_level_appleset.objects.all()
Django外鍵(ForeignKey)操作以及related_name的作用
之前已經寫過一篇關於Django外鍵的文章,但是當時並沒有介紹如何根據外鍵對數據的操作,也就是如何通過主表查詢子表或者通過子表查詢主表的信息
首先我定義了兩個模型,一個是老師模型,一個是學生模型,一個老師對應多個學生,這個算是一個一對多的類型(如下圖所示)
那么如果我們要想查詢一個老師對應的學生有哪些,該如何操作呢?
首先我們先查詢到老師的信息,在這里我們使用python shell 進行演示 ,輸入命令python manage.py shell 進入python shell操作界面:
第一步需要做的自然還是需要將我們的模型導入進來,並獲取老師的相關信息
返回一個teacher對象,接下來就是查詢teacher相關聯的學生對象,在這里有一個需要注意的點,django默認情況下每一個主表的對象都有一個是外鍵的屬性,可以通過它查詢到所有關於子表的信息,這個屬性的名字就是子表的名稱小寫加上_set,具體到這個就是student_set,默認返回的是QuerySet,操作如下:
在這里也會牽涉到另外一個知識點related_name的使用,在models.py使用Foreign定義外鍵的時候也可以傳入一個參數related_name,操作如下:
執行python manage.py makemigrations 和 python manage.py migrate
從上圖可以看到和之前的_set操作的效果是一樣的,這兩個方法是相同的,所以如果覺得比較麻煩的話,可以在定義主表的外鍵的時候,直接就給外鍵定義好名稱使用related_name
上面的查詢主要是通過主表查詢子表的信息
下面說一下如何通過子表查詢主表的相關信息,也就是查詢一個學生所對應的老師的信息
首先需要先獲取一個子表的對象,那么就可以通過定義外鍵時候的那個外鍵的字段名獲取關於主表的信息了
比如我得到了一個student對象,然后我想要得到這個student對象對應的主表teache中的信息的話,就使用 student.teacher 獲取,其中這個teacher就是在子表中定義的外鍵字段,如下: