Alright, this is probably a really silly question but I am new to Python/Django so I can't really wrap my head around its scoping concepts just yet. Right now I am writing a middleware class to handle some stuff, and I want to set 'global' variables that my views and templates can access. What is the "right" way of doing this? I considered doing something like this:
from django.conf import settings
class BeforeFilter(object):
def process_request(self, request):
settings.my_var = 'Hello World'
return None
from django.conf import settings
from django.http import HttpResponse
def myview(request):
return HttpResponse(settings.my_var)
Although this works, I am not sure if it is the "Django way" or the "Python way" of doing this.
So, my questions are:
1. Is this the right way?
2. If it is the right way, what is the right way of adding variables that can be used in the actual template from the middleware? Say I want to evaluate something and I want to set a variable headername
as 'My Site Name' in the middleware, and I want to be able to do {{ headername }}
in all templates. Doing it the way I have it now I'd have to add headername
to the context inside every view. Is there anyway to bypass this? I am thinking something along the lines of CakePHP's $this->set('headername','My Site Name');
3. I am using the middleware class as an equivalent of CakePHP's beforeFilter
that runs before every view (or controller in CakePHP) is called. Is this the right way of doing this?
4. Completely unrelated but it is a small question, what is a nice way of printing out the contents of a variable to the browser ala print_r
? Say I want to see all the stuff inside the request
that is passed into the view? Is pprint
the answer?
You can use middleware if you want to modify the request i.e HttpRequest object which is sent to the view. Or you might want to modify the HttpResponse object returned from the view. Both these can be achieved by using a middleware. You might want to perform an operation before the view executes.
Middleware is a framework of hooks into Django's request/response processing. It's a light, low-level “plugin” system for globally altering Django's input or output. Each middleware component is responsible for doing some specific function.
The include tag allows you include a template inside the current template. This is useful when you have a block of content that are the same for many pages.
Custom middleware in Django is created either as a function style that takes a get_response callable or a class-based style whose call method is used to process requests and responses. It is created inside a file middleware.py . A middleware is activated by adding it to the MIDDLEWARE list in Django settings.
It's not the best way. You could set my_var on the request rather than on the settings. Settings are global and apply to the whole site. You don't want to modify it for every request. There could be concurrency issues with multiple request updating/reading the variable at the same time.
To access request.my_var in your templates you could do {{ request.my_var }}. To get access to the request variable in your template you will have to add django.core.context_processors.request to your TEMPLATE_CONTEXT_PROCESSORS setting.
Yes. Other terminology to describe request middleware would be request pre-processor/filter/interceptor.
Also, if you want to use a common Site name for the header in your templates, you might want to check out the Django Sites application which provides a site name variable for your use.
Here's what we do. We use a context processor like this...
def context_myApp_settings(request):
"""Insert some additional information into the template context
from the settings.
Specifically, the LOGOUT_URL, MEDIA_URL and BADGES settings.
"""
from django.conf import settings
additions = {
'MEDIA_URL': settings.MEDIA_URL,
'LOGOUT_URL': settings.LOGOUT_URL,
'BADGES': settings.BADGES,
'DJANGO_ROOT': request.META['SCRIPT_NAME'],
}
return additions
Here the setting that activates this.
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.request",
"myapp. context_myApp_settings",
)
This provides "global" information in the context of each template that gets rendered. This is the standard Django solution. See http://docs.djangoproject.com/en/dev/ref/templates/api/#ref-templates-api for more information on context processors.
"what is a nice way of printing out the contents of a variable to the browser ala print_r?"
In the view? You can provide a pprint.pformat
string to a template to be rendered for debugging purposes.
In the log? You have to use Python's logging
module and send stuff to a separate log file. The use of simple print statements to write stuff to the log doesn't work wonderfully consistently for all Django implementations (mod_python, for example, loses all the stdout and stderr stuff.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With