This doesn't make great sense - why is this particular kind of complexity a bad thing?
Most Python frameworks, regardless, seem to score quite well-Flask, Turbogears, Bottle-in contrast to Django, which is to be expected as it doesn't try to be simple (it is, however, well documented and easy to learn).
According to the Wikipedia article increased cyclomatic complexity leads to harder test code and the increased likelihood of more defects.
I'm curious how the analysis in the blog post works. In languages like Python it's common to hide branches inside of data structure lookups like the following:
Slightly off-topic but why would you build up a dictionary in h(), then index it, then call the function being returned? The dictionary must be garbage collected later too. To me this seems rather inefficient compared to a simple if/then/else. I think readability also suffers.
It's likely the parent has listed this way for brevity of the post, while still trying to show the potential for complexity, which I believe is the key point here and i would agree with it.
The dict-as-a-switch expression is common to python, but it can be masked as the parent has shown in larger examples.
I have no idea how we could apply static analysis techniques to a construct like this. To be honest I tend to avoid this approach on readability grounds. It could be cleaned up with a dict subclass but I think inlining the dict call mechanics is simpler to read, even if it produces larger code, leads to repetition and couples you to this approach (which would be a strong consideration in the case of writing a library - where this type of code is most prevelant).
I find django's level of complexity just about right. It has a lot of built-in things that you might not need in every case, but they might come handy some of the times. But what makes me stick with django is that it is low level enough to allow me to build whatever I want while smoothing the process.
I would call Django everything but low-level. Tornado, Twisted.Web and (possibly) CherryPy are low-level, Flask, Bottle, Web.py and other micro-frameworks I consider mid-level and Django, Pyramid and other "full-stack" frameworks are definitely high-level.
And Django's complexity is really good in it's class. "Complex is better than complicated" - and Django tries hard not to be the latter :)
I usually just route a json request to a python function and send a response. And I've found the ORM which would be the most high level part of it to do everything I've needed to do which without tweaking anything.
And you're doing this utilizing Django's urlconf machinery?! With all it's support for deeply nested hierarchies of urls, passing keyword and other arguments extracted from url (and/or just supplied), supplying views as strings instead of function objects etc, not to mention setting settings.py up?
Look, I know that bare-bones Django looks simple, but in reality it isn't. You don't even have "bare-bones" unless you manually disable quite some functionality in settings.py. It's still good if you plan to grow your app. You can always turn the features back on and plug reusable apps with ease.
But for something as simple as getting JSON requests, hitting db and returning response I'd choose something else, some microframework and simplified ORM, for example Bottle and Storm[1]. I had a great success with using CorePost[2] on top of Twisted, but that's only if you can live without an ORM and like Twisted's brand of async.
Long story short: there is no need to employ Django for every little webservice. You can, of course, but you should think about why your using full-stack framework when something simpler, faster and smaller would do just as well.
I understand what you're saying. Is that kind of magic that makes effortless the making of these simple things. And that's what's expected in a framework. But you are right, when compared to other smaller python frameworks django turns out as more complex. But let's say, compared to other frameworks like .NET for example, django stays in a lower which I like and I don't need more.
Django is a whole different beast though. It comes with the kitchen sink and its own cheeseshop. It was designed to cater for every single edge case, but in my opinion, is the very definition of excessive complexity.
Most of the things aren't needed by most people, but it gets installed anyway.
EDIT: I am an idiot who clearly doesn't know much about Django and spake without prior research.
A) The kind of complexity you're referring to is different from what this blog post is talking about. (Specifically cyclomatic complexity.)
B) Django doesn't have its own cheeseshop. Django developers use PyPI and pip just like everyone else. (Maybe you're thinking of Crate.io, which is a PyPI mirror that happens to use Django in its implementation.)
Oh. Thanks for setting me straight on the cheeseshop (I actually thinking that since it has its own package management system, it would have its own cheeseshop) Sorry.
As for complexity, I still think it's excessive. It's good to know the internals of a module/package/whatever, and django is really really complex, of which cyclomatic complexity quantifies I believe. I mean, if you have code that branches off everywhere, it'd be hard to follow the logic when inspecting the internals.
One of the first few pages in the tutorial includes:
"Django apps are "pluggable": You can use an app in multiple projects, and you can distribute apps, because they don't have to be tied to a given Django installation."
and I guess it might be possible to mistake 'manage.py startapp ...' as some sort of internal packaging thing if you don't look too deeply.
To answer your question: I am an idiot and I didn't know much about Django. I did once find djangopackages or something like that and simply jumped to the conclusion. Big and Unwieldly is the brand perception I had.
The overwhelming majority of functionality in Django is useful for day to day web development. An argument could be made that a few bits of contrib and stuff like databrowse should be culled but they are completely separate from the rest of the framework and don't add to the conceptual complexity in any meaningful way.
And catering to 'every single edge case' actually seems to contradict the philosophy I've observed on the django-developers list.
Most Python frameworks, regardless, seem to score quite well-Flask, Turbogears, Bottle-in contrast to Django, which is to be expected as it doesn't try to be simple (it is, however, well documented and easy to learn).