Is there a way to access the context from everywhere in Django?

前端 未结 3 1881
执笔经年
执笔经年 2020-12-10 05:49

I\'m looking for a way to have a global variable that is accessible by any module within my django request without having to pass it around as parameter. Traditionally in ot

相关标签:
3条回答
  • 2020-12-10 05:52

    You have to write your own ContextProcessor, like explained here.


    EDIT:

    After you've created a Context Processor, e.g.,

    def ip_address_processor(request):
      return {'ip_address': request.META['REMOTE_ADDR']}
    

    you can get the variables you need by initializing a RequestContext, like this:

    from django.template import RequestContext
    
    def myview(request):
      rc = RequestContext(request)
      rc.get('ip_address')
    

    However, please note that if you don't put your Context Processor inside the TEMPLATE_CONTEXT_PROCESSORS tuple, you have to pass the processor to RequestContext as an argument, e.g.:

    from django.template import RequestContext
    
    def ip_address_processor(request):
      return {'ip_address': request.META['REMOTE_ADDR']}
    
    def myview(request):
      rc = RequestContext(request, processors=[ip_address_processor])
      rc.get('ip_address')
    

    Some useful links:

    • Django Template API documentation
    • Settings TEMPLATE_CONTEXT_PROCESSORS
    • Django Book: Advanced Templates
    0 讨论(0)
  • 2020-12-10 06:00

    It's still not completely clear to me what you're trying to achieve, but it sounds like you might want something like the following.

    If you create a piece of middleware in, say...

    myproject/myapp/middleware/globalrequestmiddleware.py
    

    ...which looks like this...

    import thread
    
    class GlobalRequestMiddleware(object):
        _threadmap = {}
    
        @classmethod
        def get_current_request(cls):
            return cls._threadmap[thread.get_ident()]
    
        def process_request(self, request):
            self._threadmap[thread.get_ident()] = request
    
        def process_exception(self, request, exception):
            try:
                del self._threadmap[thread.get_ident()]
            except KeyError:
                pass
    
        def process_response(self, request, response):
            try:
                del self._threadmap[thread.get_ident()]
            except KeyError:
                pass
            return response
    

    ...then add it into your settings.py MIDDLEWARE_CLASSES as the first item in the list...

    MIDDLEWARE_CLASSES = (
        'myproject.myapp.middleware.globalrequestmiddleware.GlobalRequestMiddleware',
        # ...
    )
    

    ...then you can use it anywhere in the request/response process like this...

    from myproject.myapp.middleware.globalrequestmiddleware import GlobalRequestMiddleware
    
    # Get the current request object for this thread
    request = GlobalRequestMiddleware.get_current_request()
    
    # Access some of its attributes
    print 'The current value of session variable "foo" is "%s"' % request.SESSION['foo']
    print 'The current user is "%s"' % request.user.username
    
    # Add something to it, which we can use later on
    request.some_new_attr = 'some_new_value'
    

    ...or whatever it is you want to do.

    0 讨论(0)
  • 2020-12-10 06:13

    You can still access the current session pretty much anywhere.

    Use:

    from django.contrib.sessions.backends.db import SessionStore
    
    ...
    s = SessionStore()
    s.session_key # unique_id
    s['myvar'] = "something"
    s.save()
    

    This of course uses the database and the sessions table, so may be a bit too much overhead. Is the variable session-specific, or is it just a global cost?

    Docs: https://docs.djangoproject.com/en/dev/topics/http/sessions/#using-sessions-out-of-views

    P.S. What I've done in the past is created my own table with a column session_id and various other things, then done the SQL to select data based on session_id manually. Much quicker than using the SessionStore() sugar

    0 讨论(0)
提交回复
热议问题