Django是一个十分重量级的框架,所以只能每次写一部分,没有办法一次性写完,更新频率要看心情😀
先来说说django常用的几个功能的实现:
runserver
首先入口点,肯定是manage.py了
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "web.settings") # 设置配置文件路径到环境变量
try:
from django.core.management import execute_from_command_line # 导包 命令行解析函数
except ImportError:
try:
import django # 导入django,验证环境中是否有django模块
except ImportError:
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?"
)
raise
execute_from_command_line(sys.argv) # 把命令行参数传入命令行解析函数
# 命令行解析函数
def execute_from_command_line(argv=None):
"""
A simple method that runs a ManagementUtility.
"""
utility = ManagementUtility(argv) # 这个类主要实现了命令行解析和处理,导入django配置文件,导包的模块加载等等,其实基本上django初始化过程应该都在这里了,这个类太长了这里就不放全部源码了
utility.execute() # ManagementUtility的execute方法主要实现了上述的命令行解析处理,导入django配置文件等等
# execute,删减了其中大部分代码
def execute(self):
try:
subcommand = self.argv[1]
except IndexError:
subcommand = 'help' # Display help if no arguments were given.
try:
settings.INSTALLED_APPS
except ImproperlyConfigured as exc:
self.settings_exception = exc
if settings.configured:
if subcommand == 'runserver' and '--noreload' not in self.argv: # 这里可以看出如果使用了runserver,就会调用以下的autoreload.check_errors方法,这个方法无可厚非,看名字也知道是个查错的,其实这就是个收集异常的闭包,这里不展开说了,django.setup这个函数参数在下方代码块,其实就是在配置日志和app
try:
autoreload.check_errors(django.setup)()
except Exception:
else:
django.setup()
self.autocomplete() # 初始化配置的,有兴趣可以看看,这里不说了。
if subcommand == 'help': # 这里判断是否是查询帮助,如果不是则正常启动
........
else:
self.fetch_command(subcommand).run_from_argv(self.argv) # 函数在下下方代码块
# django.setup
# 这里的注释可以看出,直接了当说明这函数干嘛的,配置setting,log和注册app
def setup(set_prefix=True):
"""
Configure the settings (this happens as a side effect of accessing the
first setting), configure logging and populate the app registry.
Set the thread-local urlresolvers script prefix if `set_prefix` is True.
"""
from django.apps import apps
from django.conf import settings
from django.urls import set_script_prefix
from django.utils.encoding import force_text
from django.utils.log import configure_logging
configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
if set_prefix:
set_script_prefix(
'/' if settings.FORCE_SCRIPT_NAME is None else force_text(settings.FORCE_SCRIPT_NAME)
)
apps.populate(settings.INSTALLED_APPS) # 初始化app(注册app)这个不展开说了
# self.fetch_command(subcommand)
def fetch_command(self, subcommand):
"""
Tries to fetch the given subcommand, printing a message with the
appropriate command called from the command line (usually
"django-admin" or "manage.py") if it can't be found.
"""
# Get commands