iT邦幫忙

2023 iThome 鐵人賽

DAY 4
0
自我挑戰組

打掉重練!Django的還債之旅~系列 第 4

Day04. 所以說runserver,阿server怎麼run的!?part.1

  • 分享至 

  • xImage
  •  

前言

在探索Django的項目,我想首當其衝的肯定是python manage.py runserver了吧!!runserver肯定是在開發Django最常用到的指令了,每次輸入完後就看他跑一些東西,然後呢~

然後server就run起來了,Django背後到底做了什麼?一行指令就讓server跑起來這是什麼黑魔法!

今天就來探索探索runserver背後的運行過程吧!

正題

開門見山的說,直接上圖
https://ithelp.ithome.com.tw/upload/images/20230919/20162905kmKhwiUOYZ.png
摁~這畫質有夠差(X
讓我把圖拆成兩份來看
https://ithelp.ithome.com.tw/upload/images/20230919/20162905ZuGRjzZ1vn.png
https://ithelp.ithome.com.tw/upload/images/20230919/20162905dFdF7XK018.png
清楚多了!
不過可以很明顯地看到他肯定做了很多事,而且我還沒列出全部上圖只是大部分我自己覺得重要的過程而已!!其他可能有點重要的部分我們之後再來深究!

接下來我會一個步驟一個步驟的走我是怎麼把這張圖畫出來的!
首先呢當然就是從指令下手python manage.py runserver,其中的manage.py不知道大家有沒有點進去看過,當中就是我們第一個探勘地點~
manage.py長這樣

#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
    """Run administrative tasks."""
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'iron_man001.settings')
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)
    # 這邊的sys.argv = [manage.py, runserver]


if __name__ == '__main__':
    main()

挺短的也挺好懂的,基本上看變數和function名稱就可以大概知道在做什麼事情了~
那我們繼續跟著execute_from_command_line(sys.argv)看下去
以下位置在 django.core.management.__init__ 裡面
https://ithelp.ithome.com.tw/upload/images/20230919/20162905W1U3aOkf69.png
new 出一個 ManagementUtility()然後execute()他,來看看execute()在做什麼~
https://ithelp.ithome.com.tw/upload/images/20230919/201629057JOkCtmKKk.png
CommandParser()是去繼承python lib的argparse.ArgumentParser()
(python argparse是一個專門處理CLI command的內建函式庫,有興趣的可以到官網看著文件手刻玩看看~)
再繼續往下挖
https://ithelp.ithome.com.tw/upload/images/20230919/20162905akQItKdoIE.png
這邊settings.INSTALLED_APPS其實就會去import settings了,這邊先挖個坑,繼續往下
https://ithelp.ithome.com.tw/upload/images/20230919/20162905nO3YwDbQN0.png
這邊註解寫的很詳細,不管怎樣都會先啟動autoreloading dev server,因為我們的command class還沒被讀到,command class!看來所有的command都會是class呢~
再繼續挖
https://ithelp.ithome.com.tw/upload/images/20230919/20162905BL10ij9xSU.png
fetch_command()run_from_argv()這兩個function好像又要做一堆事情了
先看看fetch_command()會return什麼
最一開始會get_commands()而此function會把django所有相關的資料夾中有commands字眼的都抓進來
https://ithelp.ithome.com.tw/upload/images/20230919/201629058R5abyS0Oq.png
接下來
https://ithelp.ithome.com.tw/upload/images/20230919/20162905PaDryxPYbt.png
照上圖所示,把該command的class import進來
到這邊fetch_command()就告一段落了~


那runserver會import哪個command class呢?而run_from_argv()又在哪呢?
這一個django.contrib.staticfiles.management.commands.runserver
我挖
https://ithelp.ithome.com.tw/upload/images/20230919/20162905LqtgFDO6a7.png
他會去繼承這個commanddjango.core.management.commands.runserver.Command
我挖
會發現該command會去繼承django.core.management.base中的BaseCommand
終於找到你了run_from_argv()
https://ithelp.ithome.com.tw/upload/images/20230919/20162905xUjeMx88tO.png
中間有些地方就先跳過,去看最下面的self.execute(*args, **cmd_options)
我挖
https://ithelp.ithome.com.tw/upload/images/20230919/201629058HALKyEjO0.png
我再挖
https://ithelp.ithome.com.tw/upload/images/20230919/20162905snrrbrObKc.png
handle()最後會去觸發run()
https://ithelp.ithome.com.tw/upload/images/20230919/20162905Wmu3jLomj5.png
run()又做了一大堆事情,我們放到明天再繼續~

結語

今天的部分大概就是最上面圖的前半段,大概就照著這樣的感覺下去挖原始碼
回顧一下最一開始的python manage.py runserver引發了那麼一大串的程式互相作用形成,真的是挺有趣的呢,只不過一些地方要稍微想一下找一下就是了~
/images/emoticon/emoticon13.gif


上一篇
Day03. Django的預設頁面跑哪去啦!?
下一篇
Day05. runserver,怎麼run起來的?真相是!?part.2
系列文
打掉重練!Django的還債之旅~30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言