前言

稍微補一下前幾篇的坑,這也是很重要的一環,所有Django框架層的設定都會在settings.py裡面,而我們在runserver的邊也有看到他是在什麼時候被import進去的,只不過沒有細講他是怎麼個import法,今天就來挖挖看settings的奧秘吧!

正題

先稍微回顧一下,據我的觀察,settings是在我們指令觸發也就是python manage.py XXX會到這邊

那這個檔案在import的時候就先把settings給new出來了

那什麼時候import的呢,在這邊

可是他這樣怎麼import,他就只是叫一下那個INSTALLED_APPS的參數而已啊,怎麼就會把所有的settings.py的東西都吃進來呢?接著看
我挖
進來django.conf.__init__.py

這邊看到真面目了!
LazySettings()看起來就是不會new出來的時候就動作
接著看

可以從這邊看到其實我們真正的目標是那個Settings(settings_module)
跳過去看看

這邊其實就可以很明顯的看到是在處理settings.py的地方了~
到這邊把上面得到的資訊整理一下串起來會變這樣:

  1. settings.INSTALLED_APPS
  2. LazySettings()
  3. _setup()
  4. Settings(settings_module)

以上,這邊會用到python的特性

magic method

在python中看到雙底線開頭雙底線結尾的變數或function__<magic method name>__就會是magic method,而其使用方法技巧妙用有很大的發揮空間,在看Django的source code的過程就可以發現大量的被使用中!

回歸正題,當今天我們呼叫settings.INSTALLED_APPS會觸發這個magic method

在這邊我又看到我不曾寫過的code

google了一下是python 3.8新功能,叫海象運算符:=,其作用是可以在表達式(expression)中給變數賦值
再回來看code就可以發現當今天self._wrapped是空的時候就會去觸發self._setup()也就是說會去import settings啦!
以上大致上就是Django如何把settings.py的變數import進來的過程
用draw.io稍微畫一下大概如下

結語

source code看了看真的能有不少的收穫,且可以看到很多pythonic的寫法,未來有機會情境對了想到之前看的source code寫法可能就可以更簡單更好看,可喜可賀!