In Django, can I set vary_on_cookie globally? - python

When developing a Django app, I can use the vary_on_cookie decorator to make sure
that upstream caches use the session cookie in addition to the URL to distinguish
between different pages.
I have a lot of view functions and all of them now require this header. Is it possible
to specify this behavior once (maybe in the settings file for the entire site or at
least for an entire app)? Or do I really have to repeat that decorator in front of every
single view function?
Thank you very much for your help...

Sounds like you will want to write your own middleware and modify each request to include any extra headers that you want included on each request.
Creating middleware is easy and you will probably be interested in the process_response method, as you can simply modify the response and you're done.
To modify the headers of an HttpResponse check out the docs here.

UsingSessionMiddleware adds Cookie to the Cache-Control headers for every request.

Related

Django middleware advised not to use request.POST why?

"Accessing request.POST inside middleware before the view runs or in process_view() will prevent any view running after the middleware from being able to modify the upload handlers for the request, and should normally be avoided."
This is from the django documentation. First of all, if I just read the POST, without changing that, how does it even know and how does it prevent the view from doing it's business and second, how is a CsrfViewMiddleware different in that sense?
The warning comes from this ticket and this.
Django currently parses the POST data lazily, but middlware might try to access POST on a request and trigger parsing, even though the function itself never touches POST.
That would put high load on the machine if the POST data is rather large ...
It means that the view will be unable to set any custom upload handlers, perform custom parsing of the request body, or enforce permission checks prior to file uploads being accepted.
And the difference about CsrfViewMiddleware is stated clearly right below the said warning in the docs:
The CsrfViewMiddleware ... provides the csrf_exempt() and
csrf_protect() decorators which allow views to explicitly control at what point the CSRF validation should
occur.

Why view functions require a request parameter In Django?

Example from Django documentation:
def index(request):
return HttpResponse('<h1>hellworld!</h1>')
def detail(request, question_id):
return HttpResponse("Question: %s" % question_id)
Since the request argument is never used, why should I include it in each function signature?
The purpose of a web server is to reply to HTTP requests (In simple terms). Django being a web framework generates responses depending on the request that it receives.
The business logic of handling the requests is done by Django Views, it is their purpose. This is why Django supplies the request to the view function, so the code can access the request data and choose what actions it should take and which response it should send back (even though that specific view doesn't make use of it).
The decision of requiring the view to receive the request as an argument is an implementation decision made by Django developers, making it part of the interface the view has with the rest of the "system". Other frameworks might choose making it available globally and not suplying it to the views/controllers directly, but the merits of one or another approach is other discussion.
Many of the examples in Django's documentation (and any documentation, really) are necessarily contrived. They're simple because the complexity of a real example would take away from the point that's being made.
In real use cases, you'll frequently want access to the request object. You may want to know which User is attached to the request (request.user) or whether the request is a GET or a POST (request.method).
You can also inspect the headers (request.headers), decode the JSON object sent with a POST request (json.loads(request.body)), etc.
Those are just examples. In real world a programmer would want to find request GET arguments, decode JSON POST body, inspect headers, get user or session data, etc.

Middleware in flask

I just stated using Flask and was trying to implement a small feature in my project. The objective is to set a cookie only if the request comes from a authenticated user.
I found two ways of doing this.
First method
#app.before_request
def before_request():
# set cookie if user is logged in
Second method, by implementing something like this
adding-a-simple-middleware-to-your-flask-application
Can someone explain to me what are the main differences between the two methods and when and where which method should be used.
Also, I am currently using "flask-login" to keep track of the logged in user.
If I use the first method, I can easily verify if someone is logged in by importing the current_user
from flask.ext.login import current_user
but if I try to do the same while using the second method, the current_user is always "None" as the application context is incorrect.
So, I wanted to know if I decided to go ahead with the second implementation, how do I check if the user is logged in or not.
I've never used the second method you've mentioned. I'm sure that it can be done with it, but it's very uncommon. I would suggest to use more common features of flask. For sake of maintainers of your code :)
So the first method you've mentioned is fine.
Or you can use decorators for more granular access restrictions. Keep in mind that setting cookies in flask can be done when making actual response object. That means you should use Deferred Request Callbacks for setting cookies in decorated function.

Defining both post and get method under same request handler

I'm using python to develop a web app.
I defined both "get" and "post" method in the same request handler to serve different purpose. That is, I use "get" method to present a form to user, and "post" method to handle the submitted form.
It works fine, but is this approach appropriate? Or should I better define get and post separately in different request handler? Thanks!
Your approach is appropriate. According to the newest documentation you can even define post and get as functions outside request handler and just as other functions in your module and that's a way I would choose since it eliminates problems that can happen when instanciating request handlers.
If starting a new app from scratch I probably would try to put my get and post function outside of request handler with the new python 2.7 runtime that according to docs supports that.

Does Django have a built in way of getting the last app url the current user visited?

I was hoping that Django had a built in way of getting the last url that was visited in the app itself. As I write this I realize that there are some complications in doing something like that (excluding pages that redirect, for example) but i thought I'd give it a shot.
if there isn't a built-in for this, what strategy would you use? I mean other than just storing a url in the session manually and referring to that when redirecting. That would work, of course, but I hate the thought of having to remember to do that for each view. Seems error-prone and not very elegant.
Oh, and I'd rather not depend on server specific referral environment variables.
No, there is nothing like that built in to Django core (and it's not built in because it isn't a common usage pattern).
Like Javier suggested, you could make some middleware which does what you want. Something like this:
class PreviousURLMiddleware(object):
def process_response(request, response):
if response.status_code == 200:
request.session['previous_url'] = request.get_full_url()
return response
This middleware would have to go after SessionMiddleware in your settings to ensure that the session will be updated after this (the docs have a pretty picture explaining why this is).
you can just write a middleware that does exactly that, no need to repeat logging code on every view function.

Categories