12
votes

Comment faites-vous quelque chose après avoir rendu la vue? (Django)

Je veux faire quelque chose après avoir rendu la vue en utilisant xxx

signale la seule façon de le faire? Dois-je écrire un signal personnalisé ou Demand_Finished me donne-t-il suffisamment d'informations? Fondamentalement, j'ai besoin de savoir quelle page a été rendue, puis faire une action en réponse à cela.

Merci.

Mise à jour des commentaires: Je ne veux pas tenir le rendu de la page, je veux donc rendre la page d'abord, puis faire l'action.


3 commentaires

Cela semble en arrière. Vous savez de quelle page vous êtes sur le point de rendre. Juste faire l'action. Pourquoi ne pouvez-vous pas simplement insérer l'action supplémentaire dans la fonction de vue? S'il vous plaît fournir un indice quant à ce que vous essayez de faire.


Je ne veux pas tenir le rendu de la page, je veux donc rendre la page d'abord, puis faire l'action


@Rick: Veuillez ne pas commenter votre propre question, veuillez mettre à jour votre question avec des faits supplémentaires.


7 Réponses :


-1
votes

En rendu à la réponse, vous passez la page HTML que vous souhaitez afficher. Cette autre page doit envoyer un message (via JavaScript ou quelque chose) qui déclenche la fonction correcte de votre point de vue, cette vue appelle la page suivante correcte à afficher.


3 commentaires

ouais ça marcherait, mais je me demande s'il y a un moyen de le faire uniquement du côté serveur


Je ne suis pas sûr que c'est vraiment possible: /


Cela ne peut certainement pas être fait le côté serveur. Le serveur ne sait rien de ce que le client fait, il ne saura donc jamais que la page a fini de rendu. Bien sûr, un message simple résoudra ce problème.



5
votes

Si vous avez un processus de longue date, vous avez deux choix simples.

  1. apparaît un sous-processus avant d'envoyer la page de réponse.

  2. Créez un "démon de service de fond" et passez des demandes de travail.

    C'est tout à l'extérieur de Django. Vous utilisez Subprocess ou une autre méthode IPC pour communiquer avec l'autre processus.


1 commentaires

D'accord - J'utiliserais une sorte d'IPC pour créer ce neutre modulaire et Web-serveur. Vous ne voulez probablement pas pirater sur Django Internals pour faire des choses après l'envoi de la réponse.



4
votes

Un moyen courant de le faire est d'utiliser des files d'attente de messages. Vous placez un message sur la file d'attente et les threads de travailleur (ou les processus, etc.) consomment la file d'attente et effectuez le travail après la fin de votre vue.

Google App Engine a la file d'attente de tâches API http://code.google. com / appengine / Docs / Python / Taskqueue / , Amazon a le service de file d'attente simple http: // aws.amazon.com/sqs/ .

Une recherche rapide n'a pas abouti de Django PluggalLables qui ressemblent à des normes acceptées.

Un moyen rapide et sale d'émuler la fonctionnalité consiste à placer le "message" dans une table de base de données et de vérifier périodiquement le tableau pour effectuer le travail.


1 commentaires

+1 une idée encore plus efficace que (espérons-le) des messages IPC légers.



5
votes

L'objet HTTPResponse de Django accepte un itérateur dans son constructeur:

http://docs.djangoproject.com/fr/dev/ref/request-response/#passing-perators p>

Pour que vous puissiez faire quelque chose comme: p>

def myiter():
    yield "my content"
    enqueue_some_task()
    return

def myview(request):
    return HttpResponse(myiter())


1 commentaires

Malheureusement, cela fera que la page semble toujours chargée du côté client après sa charge entièrement chargée, car le serveur ne ferme pas la connexion tant que le résultat final n'est pas donné.



2
votes

Ma solution préférée: un processus distinct qui gère les tâches d'arrière-plan, typiquement des choses telles que l'indexation et l'envoi de mails de notification, etc., puis, lors du rendu d'affichage, vous envoyez un événement au système de traitement des événements (je ne sais pas si Django en a une intégrée, mais vous en avez toujours besoin de toute façon, vous devez donc en avoir un) et le système même met ensuite un message dans une file d'attente de message (qui est trivial pour écrire sauf si vous avez plusieurs machines ou plusieurs processus d'arrière-plan) qui font la tâche dans question.


0 commentaires

11
votes

vous apparutez un fil séparé et faites-le faire l'action.

t = threading.Thread(target=do_my_action, args=[my_argument])
# We want the program to wait on this thread before shutting down.
t.setDaemon(False)
t.start()


1 commentaires

J'ai essayé cette mise en œuvre. Apparemment, le deuxième fil lancé se termine même si sa tâche n'est pas encore terminée. Dans mon cas, il met à jour plusieurs entrées de DB



-2
votes

Peut-être que je ne comprends pas votre question. Mais pourquoi pas quelque chose de simple comme: xxx


3 commentaires

Une fois qu'il est retourné, la vue sera rendue droite? Indépendamment de ce qui se passe dans la section enfin? Si oui, c'est ce dont j'ai besoin!


Cela ne semble pas que cela fonctionne. Le rendu est retenu pendant que le code dans le final est en cours d'exécution.


Lorsqu'il y a une clause enfin, le retour de la fonction ne se produit que après le code dans enfin exécuté, cela ne fonctionnera donc pas comme prévu.