Search code examples
djangopycharm

django - settings.py seems to load multiple times?


EDIT I miscounted - it is printed out twice, not four times.

I put this in my settings.py

print 'ola!'

and on startup "ola" is printed out twice! This seems like something is wrong with my pycharm django project ... any ideas why this would happen? It isn't in a loop or anything (that i'm aware of, anyway)

cheers!

YAY The user known only as "rohit", as per the comments, has determined that a solution can be found here: https://stackoverflow.com/a/2110584/1061426 ~ see the comment about disabling reloading.

CAUTION I don't have my Django code up and about now, so I don't know what the noload will do. Good luck, soldiers.


Solution

  • If you print out the process ID and thread ID within settings.py, you will see that settings.py is actually being loaded by two different processes.

    Example showing the process and thread IDs:

    # Add to settings.py
    
    import os
    import threading
    
    print(f"Process initiated by StatReloader: {os.environ.get("RUN_MAIN")}")
    
    # Print thread iD, also available from threading.current_thread().ident
    print(f"Thread ID: {threading.get_ident()}")
    
    # Print process ID
    print(f"Process ID: {os.getpid()}")
    
    # Print parent process ID
    print(f"Parent Process ID: {os.getppid()}")
    

    Example output for Django 5.1.5:

    Process initiated by StatReloader: None
    Thread ID: 8561463168
    Process ID: 83990
    Parent Process ID: 70178
    
    Process initiated by StatReloader: true
    Thread ID: 8561463168
    Process ID: 84075
    Parent Process ID: 83990
    
    Watching for file changes with StatReloader
    Performing system checks...
    

    In my case, process id 70178 (zsh) ran the Django python process (83990) which then ran the Django python subprocess (84075) that includes the StatLoader.

    When you run python manage.py runserver, the Django code starts and then execs a Django python subprocess with the RUN_MAIN environment variable set to "true". This subprocess enables StatReloader, which includes a file watcher and is responsible for the dynamic reloading of Django whenever it sees that a source file has been changed.

    If instead you run python manage.py runserver --noreload you will only see settings.py loaded once, and you will lose the dynamic file-watching StatLoader.

    See this stackoverflow response and this article for more info. Also see a related post on Django runserver running two processes, one for StatLoader.