start

In the last section, we saw how Django handles requests.

So how does Django import app modules?

What we know.

Running Django applications is divided into production and local development modes. One runs in production via wsgi.py and the other runs in local development via manage.py runServer.

However, we noticed that both entries have a django.setup() step.

Both points have some differences, but the overall function is similar.

start

Let’s start with the setup function.


def setup(set_prefix=True):
    "" configure logging and application registration. "" "
    The apps here is a singleton that points to the apps class in Django /apps/ Registry
    from django.apps import apps
    from django.conf import settings
    from django.urls import set_script_prefix
    from django.utils.log import configure_logging

    Read the LOGGING_CONFIG configuration log file from the Settings file
    configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
    This is only valid in development mode and is ignored in production
    if set_prefix:
        set_script_prefix(
            '/' if settings.FORCE_SCRIPT_NAME is None else settings.FORCE_SCRIPT_NAME
        )
    Get the INSTALLED_APPS configuration from Settings
    apps.populate(settings.INSTALLED_APPS)

Copy the code

Next, we move to the function under POPULATE.


def populate(self, installed_apps=None):
    """ Load application configuration and model Import each application module, and then import each model module. It is thread-safe and idempotent, but not reentrant. "" "
    if self.ready:
        return

    # Threads created on the server may call 'populate' in parallel before the WSGI callback is initialized
    # set thread lock here
    with self._lock:
        if self.ready:
            return

        # RLock prevents other threads from entering this section. The following comparison and setup operations are atomic.
        if self.loading:
            # Prevent reentrant calls to avoid running AppConfig.ready()
            # methods twice.
            raise RuntimeError("populate() isn't reentrant")
        self.loading = True

        # Stage 1: Initialize app configuration and import app model
        for entry in installed_apps:
            if isinstance(entry, AppConfig):
                app_config = entry
            else:
                # Here we create an application instance using a factory method
                app_config = AppConfig.create(entry)
            if app_config.label in self.app_configs:
                raise ImproperlyConfigured(
                    "Application labels aren't unique, "
                    "duplicates: %s" % app_config.label)

            Load into the app_configs configuration
            # key is the app tag and the value is the app instance
            self.app_configs[app_config.label] = app_config
            app_config.apps = self

        # Detect duplicate app names to ensure uniqueness
        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))

        # Set the app load completion flag
        self.apps_ready = True

        # Phase 2: Import the model module
        for app_config in self.app_configs.values():
            app_config.import_models()

        Clear the cache
        self.clear_cache()

        # set the model load completion identifier
        self.models_ready = True

        # Stage 3: Run the ready method in app
        for app_config in self.get_app_configs():
            app_config.ready()

        Initialization is complete
        self.ready = True

Copy the code

conclusion

So far, when we run a Django application, we call Djangos setup method, which loads all the applications and models.