2010-03-03 17 views
5

मैं अनुरोध_फिनिश सिग्नल का उपयोग करके HttpRequest को कैसे प्राप्त और उपयोग कर सकता हूं?मैं request_finished सिग्नल कॉलबैक से अनुरोध कैसे प्राप्त करूं?

लॉगिंग उद्देश्यों के लिए यूआरएल निकालने में रूचि है।

import logging 

def write_to_file(sender, **kwargs): 
    logging.debug(type(sender)) 
    logging.debug(dir(sender)) 

from django.core.signals import request_finished 
request_finished.connect(write_to_file) 

उत्पन्न करता है इस

2010-03-03 13:18:44,602 DEBUG <type 'type'> 
2010-03-03 13:18:44,602 DEBUG ['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', '_get_traceback', 'apply_response_fixes', 'get_response', 'handle_uncaught_exception', 'initLock', 'load_middleware', 'request_class', 'response_fixes'] 
+0

मुझे यकीन नहीं है कि आप कर सकते हैं। क्या आपने कीवर्ड तर्कों को देखने की कोशिश की थी? यदि आप बस हर अनुरोध पर कुछ जानकारी लॉग इन करना चाहते हैं, तो आपको मिडलवेयर फ्रेमवर्क http://bit.ly/axVgOj का उपयोग करना चाहिए। – buckley

+1

'प्रेषक 'मॉडल वर्ग है, उदाहरण नहीं। यदि आवृत्ति डेटा प्रदान किया गया है, तो आप इसे '** kwargs' में पाएंगे, हालांकि' request_finished' में कोई भी इंस्टेंस डेटा शामिल नहीं है। आप इसके बजाय 'post_save' सिग्नल का उपयोग करने में सक्षम हो सकते हैं। यदि आपके पास समय लेने वाला कार्य है कि आप अनुरोध को पूरा करने से पहले इंतजार नहीं करना चाहते हैं, तो इसे 'थ्रेड .start_new_thread (kwargs.get ("instance") कहें। Do_something_time_consuming,())। – henrikstroem

+0

django राज्य पर दस्तावेज़ यह एक वर्ग है और एक उदाहरण नहीं है। https://docs.djangoproject.com/en/1.9/ref/signals/#request- परिभाषित क्यों एक पूरी तरह गलत जवाब स्वीकार किया गया है? – dalore

उत्तर

-1

sender.request_class.get_full_path() 

या

sender.request_class._get_request() 
का प्रयास करें:

वर्तमान कोड कुछ इस तरह दिखता

या, यदि आप middleware के साथ ऐसा करने का प्रयास करना चाहते हैं, जैसा कि पहाड़ों के सुझाव के अनुसार, यहां snippet that demos request timing using middleware है।

+3

उलझन में। क्या यह ओपी के सवाल का जवाब था? अनुरोध वर्ग पर किसी भी अनबाउंड विधि को कॉल करने के परिणामस्वरूप केवल 'स्वयं' तर्क नहीं होने के बारे में शिकायत करने का परिणाम मिलता है। (चूंकि, आप जानते हैं, यह अनबाउंड है।) – Chuck

+0

@Chuck हाँ, मुझे लगता है कि यह किया था। उदाहरण के लिए आपको '_get_request()' विधि का आह्वान करना पड़ सकता है। –

+0

@Chuck सही है। इस अनबाउंड विधि को कॉल करना स्पष्ट रूप से – jamylak

2

अनुरोध के लिए Django दस्तावेज अनुरोध_फिनिश राज्य वे कक्षा को उदाहरण प्रदान नहीं करते हैं (सुनिश्चित नहीं है कि यह उदाहरण प्रदान करने के लिए और अधिक उपयोगी क्यों होगा)। https://docs.djangoproject.com/en/1.9/ref/signals/#request-finished

तो सिग्नल बस आपको पता है कि एक अनुरोध समाप्त हो गया है, लेकिन इसका अनुरोध या कोई विवरण नहीं है। अनुरोध प्राप्त करने के लिए आपके पास 2 विकल्प हैं। एक, जिसका उल्लेख किया गया है, अनुरोध को मिडलवेयर में थ्रेड स्थानीय स्टोरेज में संग्रहीत करना है।

यहां एक उदाहरण है जो अनुरोध को संग्रहीत करता है। लेकिन आप इसका इस्तेमाल उन कार्यों को स्टोर कर सकते हैं जिन्हें अंत में बुलाया जाएगा।

import collections 
import threading 

import structlog 
from django.utils.cache import patch_vary_headers 

logger = structlog.get_logger() 

thread_locals = threading.local() 


def get_current_request(): 
    """ 
    This will return the current request object 
    but if the response has been returned the request 
    object will be cleaned up 
    """ 
    return getattr(thread_locals, 'request', None) 


def request_queue(func, func_id=None, *args, **kwargs): 
    """ 
    Helper function to queue up a function 
    and arguments to be run at the end of the request 
    if no request, will run straight away 
    Usage: 
    request_queue(function_to_run, args=(args1, args2), kwargs={'key':'value'}) 
    """ 
    request = get_current_request() 
    if not request: 
     # run the func 
     func(*args, **kwargs) 
     return 
    # else 
    # use the supplied id if given 
    if not func_id: 
     # otherwise use the memory address 
     func_id = id(func) 
    # store the func and arguments as a tuple under the func id 
    request.queue[func_id] = (func, args, kwargs) 


class RequestQueueMiddleware(object): 
    """ 
    Use this middleware to get access to the request object 
    and to use it to queue functions to run 
    """ 

    def process_request(self, request): 
     thread_locals.request = request 
     # each request gets a new queue 
     request.queue = collections.OrderedDict() 

    def process_exception(self, request, exception): 
     self.process_queue(request) 
     self.cleanup() 

    def process_response(self, request, response): 
     self.process_queue(request) 
     self.cleanup() 
     return response 

    def cleanup(self): 
     try: 
      del thread_locals.request 
     except AttributeError: 
      pass 

    def process_queue(self, request): 
     if not request: 
      request = get_current_request() 
     if request and hasattr(request, 'queue'): 
      for (func, args, kwargs) in getattr(request, 'queue', {}).itervalues(): 
       func(*args, **kwargs) 
      del request.queue 

समारोह get_current_request आयातित और किसी भी अन्य विधि में प्रयोग किया जाता है जब आप वर्तमान अनुरोध करने के लिए उपयोग की जरूरत जा सकता है।

फ़ंक्शन request_queue आपको निष्पादित करने के लिए एक फ़ंक्शन और तर्कों को कतारबद्ध करने की अनुमति देता है। एक सुविधा यह है कि आप कई बार एक महंगे समारोह को कतारबद्ध कर सकते हैं और इसे केवल एक बार निष्पादित किया जाएगा।

तो आपके request_finished हैंडलर में आप वर्तमान अनुरोध प्राप्त करने के लिए get_current_request पर कॉल कर सकते हैं। लेकिन उपरोक्त कार्यान्वयन में आपको क्लीनअप कोड को हटाने की आवश्यकता होगी। मुझे नहीं पता कि थ्रेड स्थानीय स्टोरेज पर अनुरोध ऑब्जेक्ट को रिसाव करना होगा या नहीं।

अन्य विकल्प जो किसी भी मिडलवेयर की आवश्यकता नहीं है, तब तक स्टैक फ्रेम का निरीक्षण करना है जब तक आप अनुरोध नहीं पाते।

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 

यदि आपके पास कोई अन्य चर नामक अनुरोध है तो यह टूट जाएगा। चेक प्रकार के लिए भी अनुकूलित किया जा सकता है।

संबंधित मुद्दे