6 ms·
> Views are functions from Request to Response in Django, The thing that irritates me about django is request is passed as an argument, and if you need if furt
by irahul 13y ago
> Views are functions from Request to Response in Django,
The thing that irritates me about django is request is passed as an argument, and if you need if further down the chain, you have to pass it around. I want the request object to be available throughout the request cycle without it being explicitly passed. I like the flask model of importing request when you need it. In Django, I can have a middleware to handle it for me:
from threading import local
_locals = local()
class ThreadLocalMiddleware(object):
def process_request(self, request):
_locals.request = request
@classmethod
def request(cls):
return _locals.request
@classmethod
def locals(cls):
return _locals
But then there are edge cases. What if the threads are being reused? What about greenlets? I am thinking of taking out the flask/werkzeug implementation of locals and LocalManager
> Very full-featured templates & helper functions.
Django templates are nice; Jinja2 is nicer:-)
> Lighter-weight microframeworks like Flask don't have this property.
I think it's not just about Flask being light weight. It's more a function of Django existing for longer and being more popular. Granted that Django itself includes lot of batteries which Flask doesn't, but the "somebody has already solved it" is mostly either an extension, or a forum/stackoverflow solution.
- nostrademons 13y agoThat's one of the things about Django that I really like and one of the things about Flask that really scares me. I'm writing a retrospective now about things I've learned in almost 5 years of working on Google Search, and the entry I just finished was "In almost every case where we allowed non-local effects, it has bitten us. Badly." The cost is in understandability, and is usually not apparent when the choice to make it a global is made. But 2 years later, things inevitably grind to a halt because bugs are being shipped and nobody has a handle on the code any more. I've cursed out having to explicitly pass arguments around many, many times before (not just with Google work; when I was doing Haskell stuff I used to curse how inconvenient it was that I needed to explicitly pass around stuff, and often wrote a state monad to hide it from myself). But I've found that over time, those apps never hit the brick wall where I'm like "I cannot deal with this anymore"; they remain maintainable, if ugly, indefinitely.
- irahul 13y ago> "In almost every case where we allowed non-local effects, it has bitten us. Badly." But the request object in flask is not global. If the guarantees break(request locals leak to other requests), it will be a problem. I never have had a request local leak in flask. On the other hand, I have ran into cases where I need the request object in django signals. A simple task of getting the full uri requires either a request object(I would say that's bad api but that's how it is in django) or configuring sites. Bad api or not, if I am in a request, I should have access to it, and Django makes it hard. Dress it up if you want to comply with "no globals" - RequestManager.get_current_request(). Though I don't see how that's any better than `from flask import request` when you know it does the equivalent RequestManager.get_current_request() internally.
- masklinn 13y ago> But the request object in flask is not global. So you're saying that if I don't use multithreading my global variables are not, in fact, global?
- irahul 13y ago> So you're saying that if I don't use multithreading my global variables are not, in fact, global? The request object is context local. If there are multiple concurrent requests, all request have different request objects. I don't know what definition of global variable you have, but this is not it.
- masklinn 13y ago> The request object is context local. The request object is a threadlocal (or, if greenlet is installed, a greenlet-local). Which is exactly the same as a global variable in a single-threaded program.
- irahul 13y ago> The request object is a threadlocal (or, if greenlet is installed, a greenlet-local). request objects aren't stored in python's thread local storage. If they were, a thread re-use will leak context local. Werkzeug uses the thread/greenlet id as key in its storage and cleans up when the request completes. > Which is exactly the same as a global variable in a single-threaded program. In a single threaded server, the context locals won't leak from one request to another. If they were global, they would. I don't see how request object has anything to do with global variables.