Still though, it seems that most people tend to go for the full-stack frameworks. Anyone here using Pylons?
1. It's a little tougher to get working "out-of-the-box"
2. It's documentation is not as "centralized" - meaning because you can use whatever template engine you want (jinja, mako, etc) and whatever db backend you want (sqlalchemy, elixir - a nice overlay on top of sqlalchemy, django ORM, etc) the docs for a particular module may or may not be in pylons docs
3. It's waaayyyy more flexible - I can't praise SQLAlchemy enough, it's freaking amazing!
I used SQLAlchemy breifly, but found myself drawn back to the Django ORM (even for non-web based projects) - can someone explain to me why they think SA is better than the Django ORM - I find the latter to be much better.
That may have changed recently (I don't know, I'm not familiar with Pylons), but it gave Django a head-start with people who didn't want to have to dig through the source to figure out how to do things.
Setting any one of them for development is easy: just install them in a virtualenv using pip. Can't say how they fare in production setups. I'm not there yet :p
It removes the need for writing my own MVC which I would have needed anyways, and doesn't force me to use anything I don't want to. It's just Python, but neatly separates the files in logical places.
Thus far, Pylons has met every single need so far outside of async I/O, for which I've turned to node.js.
Contrary to popular belief, Pylons is not for intermediate Python users. I've taught web development in Python to beginners using Pylons and it's not hard at all to pick up for them.
Could someone who has used it comment on how it compares to Django?
That said, I personally prefer repoze.bfg over all of them now. Also minimal, built on wsgi, but also built on the Zope Component Architecture ( just the ZCA, does not depend on the ZODB or Zope server). For really being able to reuse and extend your code, that ZCA infrastructure is the killer feature.
Pylons was built by a bunch of people with different goals in mind. One was to make an awesome ORM. Another was to make a kickass templating language[1]. The purpose of Pylons is to make it easy to integrate your choice of optimal components into a web framework with reasonable ease.
Yes, if you're going to deviate from the defaults things may not work "out of the box" like Django, and you might not get a default auth system and an admin panel (could use something like repoze). While it'll take you longer to build the initial prototype in the first week, you wont hit that wall of "why do I have to put code in 4 places to add a template tag?" or "why am I getting weird PYTHONPATH-related side effects from using settings.py?" or "oh well, I guess I just wont use joins."
The ramp-up time/results curve of Pylons is steeper than Django's, but it stays relatively steady throughout your project, whereas a monolithic framework will get more and more in your way over time until you realize you've slowly dismantled the entire framework and reinvented Pylons.
[1] Incidentally, both SQLAlchemy and Mako Templates are founded by the same person, but historically Pylons has defaulted to whatever "the best" package was (SQLObject and Kid, a few years ago).
A short comparison to Django:
- SQLAlchemy is badass.
- Jinja2 (or whatever templating language you like) is also badass.
- Passing data to your templates using a global 'c' object is weird and seems rather hack-ish to me.
- None of the third party form libraries are as good as Django's forms, especially when it comes to ModelForms (FormAlchemy's API is rather lacking, IMO). WTForms is the best I've seen so far, but it's lacking model integration.
- Both of the major user auth systems (AuthKit and repoze.who/repoze.what) are lacking compared to Django's contrib.auth. I found them convoluted, somewhat overengineered, and difficult to set up. Doing authentication in the middleware layer is the wrong approach, IMO. You shouldn't have to shuffle user data and login state around using redirects, query strings, and environment variables. If you search around on this topic, a lot of people end up recommending rolling your own. Blargh.
- Pylons puts a lot of cruft in your project when you create an new project. I'm not convinced how much of this stuff is actually necessary, especially at the beginning of a project.
- The docs have tended to lag behind the actual releases. For example, at one point url_for() was deprecated in favor of url(), but a lot of the docs still referenced it and it was not obvious where to find the documentation for url(). In fact, it's still not obvious. Sometimes you see TODOs in the documentation itself that make you wonder how up to date the docs actually are. Hopefully this has improved since I last used it.
My biggest issue with Pylons is when you run into needing a third party library like forms or user auth, you have to spend time researching 2342 different libraries, only to discover that many of them have fallen into disuse, or are poorly documented. On the other hand, it's great when it lets you choose well written components like SQLAlchemy and Jinja2.
Django and Pylons both have their pluses and minuses, but I think there is still a lot of room for improvement in the Python web world. Armin Ronacher seems to be making lots of progress with Flask, maybe we'll see that grow into a bigger project.
The way you identify a user is to pull the 'repoze.who.identity' out of environment variables. The way you detect a failed login is to check whether the login count, passed as a query string in a specially named __logins variable, is greater than zero. This especially seems like an ugly hack to me.
Oh, and I really didn't like the fact that the latest release of repoze.who (2.0a1) has a ton of undocumented, backwards incompatible API changes. It was amusing trying to get it working, only to realize that the docs only referenced a much earlier release.
I understand the goals of repoze.who and think they've written a very impressive set of plugins, and I understand how it would be useful if your app happened to have multiple types of authentication that made sense to handle at the middleware level: HTTP Basic or LDAP or whatever.
But they've done that at the expense of keeping the base case simple: having a user model with a username and password that authenticates at the application level with a login form. 99% of websites use this approach so I was surprised that it wasn't simpler to do, especially coming from Django where this feature ships by default.