I have tried to be happy with django, I really have.
reddit.com
reddit.com
One valid point he makes is: "Confusion on where to put code, and too much flexibility". Can't say how it is in other frameworks, having never used them, but The Django Book had far too many cases of saying "you can do it here or there, it's a personal preference". I don't want to make a choice when I'm new to a framework, I want to be told what's correct and what isn't!
That's why Django's "flexible" approach seems odd to me.
Django unambiguously states where to put your models, view functions, forms and the url patterns. Those are grouped into an 'application', which you can have many and define logically by the general task you want them to solve.
Inside the model, view, form and url files (settings too for that matter) you write your code according to the style and philosophy of Python.
For that reason Django can not and must not define for you in what other file should you keep and what name should you assign to some class you write that is required for one of your views or another.
If you don't feel comfortable with the structure of your Django code, it's best to look into general good practices of Python programming, because Django is Python!
class SomeModel(...): ...
class SomeOtherModel(...): ...
or from some.other.place import SomeModel
from yet.another.place import SomeOtherModel
and it's the same. Django is Python.In fact this is another instance of what I complained about yesterday: http://news.ycombinator.com/item?id=1605928 People see the "DSL" and all knowledge of the underlying language goes flying out the window. Models are actually very, very non-magical, and anything that you do that ends up with class in the certain namespace simply is a model, and any Python language feature that lets you produces such a class can be used to make one.
I have used Rails, but my web framework of choice is Tornado; I really like their design choices.
Take for example contrib.auth - it defines User, Group and Permission models for you. Frequently this is an issue - what if I don't want a username of 30 characters ? What if I want OpenID authentication instead ?
Sure, you can override this but then you find that a whole lot of 3rd party apps - comments, admin etc - rely on these models, which in turn depend on lower-level functionality such as the ORM or templates. The very fact that you have a framework telling you what your data model should look like just feels "wrong".
Does this mean that you shouldn't use Django ? Absolutely not, there are many projects suited to Django - especially content sites where you are putting together large building blocks with some homemade glue. But I've found it more trouble than worth for smaller projects, or where you have very specific requirements - in these cases (assuming you want to stay in Python) - I'd recommend Flask or Pylons.
Unfortunately Django has become the new Blub framework for Python web development, which means it's used by companies by default, rather than being a useful but limited tool in the toolbox.
1. The framework should not define your data model.
2. Many 3rd party apps depend on the existing User and other auth models.
So what do I want ? For authentication there are some common requirements:
- session/cookie management to store a user ID (or other info)
- hooks/middleware/whatever to allow me to check user credentials on each request
- safe hashing/encryption of passwords
- form processing/validation
- integration with OpenID, oAuth, LDAP etc
If a framework, or libraries, provide these then that saves a lot of time and effort, and allows me to create a tailor-made solution.
contrib.auth can be made to do most of these if you still want the ability to play nice with other people's code who expect you to use auth. You'll have to create and manage User objects which it sounds like you're unwilling to do, but you can't have it both ways.
I think having it there is better than not. In most circumstances it saves me a lot of time. If I come across a circumstance that I can't use it then I'm just back to where I would be anyways and will have to write a lot more code and modify 3rd party apps.
When I want to do something more original and specific where I don't need all those apps, Django just gets in the way - and that's when I turn to a more lightweight and flexible framework.
Use the best tool for the job. Sometimes Django is that tool. The problem I have is with companies and individuals who think it's the only tool.
The main reason (in my opinion) that Django has an authentication component is because it has an admin section. That requires authentication. The admin section is something to be jealous of because it's a lot harder to duplicate. Creating a user model isn't that hard. While there have been Rails projects trying to implement an admin system as nice as Django's, they aren't as nice and clean as I'd like. And that's a lot more complex than a simple User model.
And yes, I'm aware that one can do lots of things to extend the Django User model. Examples: while the User model doesn't require an email, you could have the form you build require an email; in Django 1.2, you can have "@" and other email characters in usernames and then just reference the username attribute rather than the email attribute when you want the email; in your controller/view, you could first search for the user by email and, if found, grab the username from that object to pass to the authenticate method. It's more that a User model isn't such an incredibly complex piece of code and I find that different sites often want slightly different things that make it just easier to make one's own.
TL;DR: Be jealous of the admin section, not the authentication system.
contrib.auth
Django is as minimal as you want it to be. People seem to have a hard time not using everything.What's left that's actually compelling about Django vs other frameworks ?
A) 2 years of programming experience in any language is not a waste of time even if you never touch that language again, B) Sunk costs, if the previous 2 years were a mistake, then don't repeat that mistake by sticking to a language and framework you don't like. C) 2 years is nothing.
At 35 now I certainly don't consider any of that time wasted. I would suggest if you are "frowning" now - as you put in your comment - to get out and do something that doesn't make you frown... the cup of coffee will still be there, I guarantee it.
+1 On the extensions - They almost never work out of the box and require extensive changes (or usually rewrites). Seems like Django people never figured out how to create portable apps for Django. (And the comment app is Horrible !)
That said, I still like Django for quickly banging out moderately complex apps.
Nginx + Django -- I have wildcard DNS on mydomain.com, and want to support customers such that customer1.mydomain.com gets its own database. I thought I'd be able to use fastcgi_param to inject a variable to fcgi, and then read it with os.environ.get('fastcgi_param'), and then 'IF' the settings.py to import customer1.settings.py (to override the database), but I can't seem to make it work.
Any thoughts?
it also seems like a much more performant idea
Why is performance important to you? Presumably to make it cheaper to run, in which case I suggest you weigh the costs of coding and maintaining multiple dbs against the cost of that extra join. Note that the multiple db approach is already costing you since you are still trying to get it to work while you could already gave the single db approach in place relatively painlessly.http://docs.djangoproject.com/en/dev/ref/contrib/sites/
Second, you could define a database backend per customer (using the Django 1.2 multi-DB support) and write a custom database router that is aware of your custom FastCGI environment variables:
http://docs.djangoproject.com/en/dev/topics/db/multi-db/
Third (and best, IMHO) would be to run separate FastCGI processes for each customer, and route appropriately from Nginx. This approach is obviously the most complex setup, but it has the major advantage of letting you run every customer's FCGI backend under a different user id, offering yet another level of protection against data leakage and other security issues.
I'll carry this over to SO, as the downvotes suggest that this is not only offtopic, but inappropriately placed altogether, but thanks a million for your insight.
I think it was just a bitching session.
You must edit models/__init__.py such that:
import X from Y
...and then each model must have class Meta:
app_label = 'foobar'
Without the meta information Django cannot load the models inside the package, it imports only models.py.May be it should be automated (model loader)? For instance, the model loader could parse the directory tree and import all necessary info it needs(meta information, optional), all is needed is a function for it :-/
edit: Format, gramer :)
edit2: Phah! OK. I'm gonna do it. Automatic model loader function, Django extension :) (May be next week...)
However, for those interested in model package loading automation, I started a section on reddit: http://www.reddit.com/r/django/comments/d1ulg/automatic_mode..., may be I'm wrong...
Sorry for bothering you...