When starting up the dev server, Django (in our case) will actually load apps (along with their apps.py, models.py, etc.) multiple:

  1. One or more times through thedjango.setup() call in django.core.management.ManagementUtility.execute().
  2. Then through the WSGI implementation in django.core.wsgi.get_wsgi_application().

Each of these are actually loaded in separate threads (verifiable by adding a import threading; print(threading.get_ident()) in django.setup()).

However, this can appear confusing when trying to debug some module initialization and seeing duplicate results. It's normal. The second invocation is what matters for the process serving the webpage.