What would be the best way of putting a bit of code to run for all views in a views.py
file?
I come from a PHP background and I normally put this in the constructor/index bit so that it always ran whatever page is being requested. It has to be specific for that views.py file though, I want to check that the user has access to 'this app/module' and want to avoid having to use decorators on all views if possible?
You should check about middlewares. It allows to execute some code before the view execution, the template rendering and other stuff.
You can represent middlewares in your head like this:
As you can see, the request (orange arrow) go through every middleware before executing the view and then can hitting every middleware after (if you want to do something before the template processing for example).
Arcitecture of middlewares have changed in Django 1.10, and are now represented by simple function. For example, here's a counter of visits for each page:
def simple_middleware(get_response):
# One-time configuration and initialization.
def middleware(request):
try:
p = Page.objects.get(url=request.path)
p.nb_visits += 1
p.save()
except Page.DoesNotExist:
Page(url=request.path).save()
response = get_response(request)
if p:
response.content += "This page has been seen {0} times.".format(p.nb_visits)
return response
return middleware
And voilà.
Using DjangoHere's an example of middleware, which would update a counter for each visit of a page (admit that a Page Model exists with two field : url and nb_visits)
class StatsMiddleware(object):
def process_view(self, request, view_func, view_args, view_kwargs):
try:
p = Page.objects.get(url=request.path)
p.nb_visits += 1
p.save()
except Page.DoesNotExist:
Page(url=request.path).save()
def process_response(self, request, response):
if response.status_code == 200:
p = Page.objects.get(url=request.path)
# Let's say we add our info after the html response (dirty, yeah I know)
response.content += u"This page has been seen {0} times.".format(p.nb_visits)
return response
Hopes this will help you :)
Middleware is the solution but keep in mind the the order to define the middleware in the settings.py matters.
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