Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Personally I'd say:

- Error handling: Django error page is great, unless of course it's a AJAX request. Pylons does this in a much smarter way

- Django ORM is awful. Easy to use yes, but awful

- Django Auth is a "good intention" but awful implementation

- Django templates are sloooooow. Jinja 2 is an order of magnitude faster

Amongst other warts

Also, the author apparently found the hard way: don't use Django as an api server

I may sound critical of Django, but I think it's a "complex framework for simple usages", I mean, if you need low flexibility go for it, you'll do what you want really quickly.



You're quick to toss out unsupported assertions: e.g. calling the ORM awful just sounds naive and microbenchmark claims about the template system assume that it's a common bottleneck, which simply isn't true.

Put another way: I inherited a site where someone noticed that a view was slow and switched everything to Jinja2 for magic pixie dust speed ups. This made almost no difference but did complicate maintenance and require reinventing common Django template tags and filters. I joined the project later and actually made the page much (50x) faster by actually profiling and not executing 8,000 SQL queries.

Jinja2 is a great project but I have yet to run into a case where the Django/Jinja debate in any way affected performance significantly. Pick the one which causes you the least support grief and worry about problems you've actually measured.


"You're quick to toss out unsupported assertions: e.g. calling the ORM awful just sounds naive"

I can assure my assertions are based by a lot of benchmarking of a Django project that heavily depended on the ORM. And it's not even about the quality of the queries, Postgres was eating them like hot cakes, but the ammount of queries itself was making it slow. Even for things like user_token.delete() (this was an open source project in Django that we were adapting)

Oh sure, I don't recommend the first step of optimization to be switching to Jinja2, Django templates are fine for 99% of cases. But in my case, Django templates were being used in a very specific way (which btw was done in the original project, that is, not by me) which was very slow (think 1s per page, and that's without querying the db!)


I would argue that the main problem is so many queries: rather than arguing about ORM dispatch speed it's almost always better to make fewer queries and/or retrieve less data as you can cut out a ton of unavoidable overhead intrinsic to shipping a query to another process (possibly on another system), executing it and handling the results. ORM improvements can only address either end of that process.

Similarly, 1s to render a template sounds rather unusual - if that's not just something like not using the cached loader on a slow filesystem it's screaming for logic to move into the view or a template tag.

I will also note in both cases these started out as general assertions which were then qualified to refer to specific edge cases. Again, without describing the exact code being benchmarked it's a disservice to through out performance advice to people who might take it as a general rule rather than understanding that it's unlikely to be a significant problem for most users.


>> "I would argue that the main problem is so many queries: rather than arguing about ORM dispatch speed it's almost always better to make fewer queries"

In Python there aren't many queries! That's the issue!

Let me explain better. Django ORM is converting a few lines (and sometimes ONE - like user_token.delete() ) of python to tens of queries. These tens of queries take around 200ms (or more) because each query takes around 3ms/10ms

user_token.delete() was taking 300ms (I wish I was kidding)

"Similarly, 1s to render a template sounds rather unusual - if that's not just something like not using the cached loader on a slow filesystem it's screaming for logic to move into the view or a template tag."

No, not cached loader, not slow filesystem. It's a for with an inner include.


If a simple delete call is generating more than one query, it's either oddly customized or you have a ton of related models which need to be updated to adjust the cascade behavior:

https://docs.djangoproject.com/en/dev/ref/models/querysets/#...

“No, not cached loader, not slow filesystem. It's a for with an inner include.”

With a lot of loops - again, not common for most web apps (who wants a 5mb HTML page?). You should be able to avoid this by using a custom template tag to load once and render many times.


I think you are being a bit harsh by using the quickness of Django as a 1 line throwaway - the entire purpose is for it to produce quick, simple applications.

There is an entire class of problems (mainly enterprise-related) for which the simplicity (ORM / Auth / etc..) is great. I managed to tie Django Auth into Active Directory which made the user's experience (relatively) seamless, as opposed to the previous reality (everyone with a different password for different applications).

Can't you also use Jinja templates in Django?

I'm not convinced that I would use Django on a large project where I get to cooperate with 15-20 other programmers, but if the scenario is 3 people with relatively normal business requirements it makes a lot of sense.

YMMV.


You can use Jinja2 with Django, but you lose the ability to use any prebuilt Django templates. Which isn't much of an issue in practice since those are often the first thing you write yourself from reusable apps.

You also can't use templatetags from reusable apps (or Django itself) but it's easy enough to write a wrapper for those that allows you to.

We switched to Jinja2 for Canvas because the Django templates were atrociously slow, and it was absolutely the right decision for us.


I don't disagree with you!

You can certainly use Jinja2 templates on Django, for most uses Django templates are ok


What is wrong with django's ORM? I'm not being flip; I'm honestly curious.


If your models are simple, it's good

If you rely on model inheritance, or your models have lots of relationships, Django uses the DB really inneficiently

Like, making lots of queries (mostly repeating itself), so a simple thing takes a lot of time.

It's a little bit difficult to explain (you can imagine it was more or less difficult to figure this out as well)


> Django templates are sloooooow. Jinja 2 is an order of magnitude faster

Template execution speed is unlikely to be the bottleneck for the vast majority of sites. I prefer Jinja2 for the flexibility (macros etc) rather than the performance.


Agree on Django auth; it's horribly designed - need an extra field - use a separate UserProfile - really? Need to login with unique email address - which EVERY SINGLE client asks for - you're going to go down a rabbit hole. A group/permissions system almost nobody uses outside the admin.

Django auth was designed around the typical use case ca. 2005. The world's moved on a bit since then.

What I end up doing nowadays is roll my own (and re-use bits of contrib.auth where appropriate, such as password hashing) using a custom auth backend and keep a separate site for the Django admin which uses contrib.auth models. As long as I don't have to use 3rd party apps that rely on auth.User I'm fine.


You can also subclass auth.User, which allows you to maintain compatibility with 3rd party apps.

This is how I've gotten around the user name length limitation. I have a longer field in the subclass, and implement a backend to check that. But because it's a subclass, foreign-key relations still work.


What if you want to get rid of the username field altogether?

For example, my typical use case: unique email address for logins, no usernames:

I suppose you could subclass User with a longer username, and sync the username with the email address using a signal, for example.

Still, it's a chunk of workaround I end up doing one way or another with each new project. Hopefully soon (based on discussions on django-developers group) we'll see some kind of pluggable User model.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: