Django app应用的配置加载过程

时间:2021-06-12
本文章向大家介绍Django app应用的配置加载过程,主要包括Django app应用的配置加载过程使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

wsgi.py

import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "apc.settings")
application = get_wsgi_application()   #获取application

django.core.wsgi.py

import django
from django.core.handlers.wsgi import WSGIHandler


def get_wsgi_application():
    """
    The public interface to Django's WSGI support. Return a WSGI callable.

    Avoids making django.core.handlers.WSGIHandler a public API, in case the
    internal WSGI implementation changes or moves in the future.
    """
    django.setup(set_prefix=False)     # Django 初始化,点进去查看
    return WSGIHandler()

django.init.py

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.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 settings.FORCE_SCRIPT_NAME
        )
    apps.populate(settings.INSTALLED_APPS)     # 从配置中读取注册的app,然后填充每个app对应的配置

django.app.registry.Apps

def populate(self, installed_apps=None):
       if self.ready:     # 保证应用配置只填充一次
           return
       with self._lock:
           if self.ready:
               return

           if self.loading:
               # Prevent reentrant calls to avoid running AppConfig.ready()
               # methods twice.
               raise RuntimeError("populate() isn't reentrant")
           self.loading = True

           # Phase 1: initialize app configs and import app modules.
           for entry in installed_apps:
               if isinstance(entry, AppConfig):    # 注册的时候指定的是AppConfig
                   app_config = entry
               else:
                   app_config = AppConfig.create(entry)   # 如果注册app时指定的是app的名称,则会根据app的default_app_config属性查找对应的配置
               if app_config.label in self.app_configs:
                   raise ImproperlyConfigured(
                       "Application labels aren't unique, "
                       "duplicates: %s" % app_config.label)

               self.app_configs[app_config.label] = app_config
               app_config.apps = self

           # Check for duplicate app names.
           counts = Counter(
               app_config.name for app_config in self.app_configs.values())
           duplicates = [
               name for name, count in counts.most_common() if count > 1]
           if duplicates:
               raise ImproperlyConfigured(
                   "Application names aren't unique, "
                   "duplicates: %s" % ", ".join(duplicates))

           self.apps_ready = True

           # Phase 2: import models modules.
           for app_config in self.app_configs.values():
               app_config.import_models()  # 根据label 确认models

           self.clear_cache()

           self.models_ready = True

           # Phase 3: run ready() methods of app configs.
           for app_config in self.get_app_configs():
               app_config.ready()    # 执行配置中定义的ready 方法

           self.ready = True

因此,配置app 有两种方式。
一种是直接定义继承AppConfig 的配置类,将该类注册在settings中;
一种是在app的settings中注册最外层的应用名称,然后给app赋值default_app_config属性,使用该属性指向定义的AppConfig 类,这种方式可以多个app共用同一个配置

原文地址:https://www.cnblogs.com/youj/p/14878763.html