2010-12-12 45 views
2

Je voudrais exécuter la méthode call_method de django dans un thread. Ce est l'exemple de code:Problème avec la commande call_command de django dans un thread

import sys 
sys.path.append("/my/django/project/path/") 
import threading 
import time 


# Import my django project configuration settings 
from django.core.management import setup_environ 
from mydjangoprojectname import settings 
setup_environ(settings) 

from django.core.management import call_command 

class ServerStarter(threading.Thread): 
    def __init__(self): 
     super(ServerStarter, self).__init__() 
     print "ServerStarter instance created" 

    def run(self): 
     print "Starting Django Server..." 
     call_command("runserver", noreload=True) 


if __name__ == '__main__': 
    starter = ServerStarter() 
    starter.start() 

------------------------------ 
OutPut: 
ServerStarter instance created 
Starting Django Server... 
ServerStarter instance created 
Starting Django Server... 
Validating models... 
0 errors found 
Django version 1.2.3, using settings 'mydjangoprojectname.settings' 
Development server is running at http://127.0.0.1:8000/ 
Quit the server with CONTROL-C. 

serveur Django démarre correctement, mais ServerStarter est créé deux fois.
Et les deux instances de ServerStarter s'exécutent.
Si je commente call_command ("runserver", noreload = True) dans la méthode d'exécution, alors seulement
un thread est créé (et c'est ce que je veux).
Merci d'avance!

+0

Sachez que cela ne va pas être une très bonne façon de le faire; Que faire si le port 8000 est pris? Ou si quelque chose d'autre veut le port 8000? À tout le moins, utilisez un numéro de port semi-aléatoire. –

+0

La même chose arrive en utilisant 'multiprocessing' au lieu de' threading'. –

Répondre

0

Je pense que cela est probablement dû au fait que le serveur interne de Django recharge tous les modules comme c'est son habitude. Essayez quoi que l'équivalent de --noreload est pour call_command (probablement call_command("runserver", noreload=True) mais je ne suis pas sûr).

(également QThread s démarrés par QApplication.exec_();. Sauf si vous avez une exigence particulière pour commencer plus tôt, je ne crois pas que vous devez exécuter starter.start() vous)

+0

J'ai supprimé les éléments graphiques de ma question. – ApprenticePython

5

J'ai trouvé une solution (Chris Morgan avait raison) . Ce code fonctionne comme je veux:

import sys 
sys.path.append("/my/django/project/path/") 
import threading 

# Import my django project configuration settings 
from django.core.management import setup_environ, ManagementUtility 

from mydjangoprojectname import settings 
setup_environ(settings) 


class ServerStarter(threading.Thread): 
    def __init__(self): 
     super(ServerStarter, self).__init__() 
     print "ServerStarter instance created" 

    def run(self): 
     print "Starting Django Server..." 
     utility = ManagementUtility() 
     command = utility.fetch_command('runserver') 
     command.execute(use_reloader=False) 


if __name__ == '__main__': 
    starter = ServerStarter() 
    starter.start()