12
votes

Comment accéder à la demande à partir du rappel de signal Demande_Finished?

Comment puis-je obtenir et utiliser le HTTPRequest à l'aide du signal Demande_Finished?

Intéressé à l'extraction de l'URL à des fins de journalisation.

Code actuel ressemble à ceci: < / p> xxx

génère ce xxx


3 commentaires

Je ne suis pas sûr de pouvoir. Avez-vous essayé de regarder le mot-clé arguments dict? Si vous souhaitez simplement enregistrer certaines informations sur chaque demande, vous devez rechercher l'utilisation de la framework Bit.ly/AXVGOJJ.


Sender est la classe modèle, pas une instance. Si des données d'instance sont fournies, vous le trouverez dans ** kwargs , cependant request_finished n'inclut aucune donnée d'instance. Vous pourrez peut-être utiliser le signal post_save à la place. Si vous avez une tâche fastiqueuse du temps que vous ne voulez pas que la demande attendait avant de finir, exécutez-la sur un nouveau thread, dites thread.start_new_thread (kwargs.get ("instance"). DO_SOME- TIME_CONSUMING ( )) .


Les docs sur Django State c'est une classe et non une instance. docs.djangoproject.com/fr/1.9/RF/Signals/# Demande de demande Pourquoi une réponse complètement fausse a-t-elle été acceptée?


3 Réponses :


-3
votes

ESSAYEZ

sender.request_class._get_request()


5 commentaires

Confus. Cela a-t-il répondu à la question de l'OP? Appeler une méthode non liée sur la classe de demande, seuls les résultats ne se plaignent que de ne pas avoir d'argument «auto». (Depuis que tu sais, c'est non lié.)


@Chuck Ouais, je pense que ça l'a fait. Vous devrez peut-être appeler la méthode _get_request () pour mettre la main sur l'instance.


@Chuck est correct. Appeler cette méthode non liée ne fonctionne évidemment pas


Guys I MA Obtenir une erreur suivante *** TypeError: Méthode non liée _GET_POST () doit être appelée à l'instance WSGIREQUEST comme premier argument (obtenu rien à la place) sur DIR (expéditeur.request_class._get_post () ) n'importe quelle idée pourquoi ??


Pourquoi diable est-ce la réponse acceptée quand il est clairement faux ?! L'expéditeur est une classe et pour moi c'était Wsgihandler. Vous pouvez voir Django l'appeler avec: signaux.Request_finished.send (expéditeur = self._handler_class) . La classe Wsgihandler n'a pas de méthodes de niveau de classe. Demande_Class Pointés de propriété à une autre classe appelée wsgirequest . Mais comme indiqué, c'est une classe afin que vous ne puissiez pas appeler des méthodes nécessitant de même que vous avez suggéré. Donc, c'est tout simplement faux.



3
votes

Documentation Django pour demande de demande_fait, ils fournissent la classe Not l'instance (pas sûre pourquoi, il aurait été plus utile de fournir l'instance). https://docs.djangoproject.com/fr/1.9/RF/ Signaux / # Demande-Terminé

Donc, le signal vous permet de connaître une demande terminée, mais pas à quelle demande ou en détail de celui-ci. Vous avez 2 options pour obtenir la demande. Un, qui a été mentionné, est de stocker la demande dans le stockage local de fil dans un middleware. P>

Voici un exemple qui stocke la demande. Mais vous pouvez utiliser des fonctions de stockage informatique qui seront appelées à la fin. P> xxx pré>

la fonction get_current_request code> peut être importé et utilisé dans n'importe quelle autre méthode Lorsque vous avez besoin d'accéder à la demande actuelle. p>

la fonction request_queue code> vous permet de faire la queue une fonction et des arguments à exécuter. Une caractéristique est que vous pouvez faire la queue une fonction coûteuse à plusieurs reprises et elle ne sera exécutée qu'une seule fois. P>

donc dans votre Demande_Finished code> gestionnaire que vous pouvez appeler get_current_request code > Pour obtenir la demande actuelle. Mais dans la mise en œuvre ci-dessus, vous devrez supprimer le code de nettoyage. Je ne sais pas si garder l'objet de la demande sur le stockage local de thread va fuir. P>

L'autre option qui ne nécessite aucun middleware consiste à inspecter les cadres de pile avant de trouver la demande. P>

def get_request():
    """Walk up the stack, return the nearest first argument named "request"."""
    frame = None
    try:
        for f in inspect.stack()[1:]:
            frame = f[0]
            code = frame.f_code
            if code.co_varnames and code.co_varnames[0] == "request":
                return frame.f_locals['request']
    finally:
        del frame


0 commentaires

2
votes

Je pense que j'ai trouvé la solution la plus simple.

regarder par Le représentant officiel de Django , J'ai trouvé la seule utilisation de requêtes_fined ici .

maintenant, je peux facilement remplacer cette méthode dans le point d'entrée dans manage.py : xxx


1 commentaires

Ça a l'air bien. Une amélioration pourrait être d'hériter de HTTPresponsebase et de mettre en œuvre une routine étroite avec un appel à «Super», alors tout ce que vous devez faire.