Over the last 3 years or so I've helped a bunch of companies, small and large, switch to Django. As part of that, I've done a lot of teaching Django (and Python) to people new to the platform (and language). I'd estimate I've trained something around 200-250 people so far. These aren't people new to programming — indeed, almost all of them are were currently employed as software developers — but they were new to Python, or to Django, or to web development, or all three.
In doing so, I've observed some patterns about what works and what doesn't. Many (most) of the failings have been my own pedagogical failings, but as I've honed my coursework and my skill I'm seeing, time and again, certain ways that Django makes itself difficult to certain groups of users.
This document is my attempt at organizing some notes around what ways different groups struggle. It's not particularly actionable — I'm not making any arguments about what Django should or shouldn't do (at least not yet) — it's simply observational, an attempt to get down in writing these themes and trends that I've noticed. The organization here is by background: how do people with different backgrounds struggle when exposed to Django?
This is a work in progress. I hope to update it as I notice new trends, and I hope to document solutions should I find them.
That is, people whose primary computing platform to date has been Windows. This includes people who develop for the Windows platform (ASP, .NET, etc.) as well as people who develop for other platforms (Java, mostly) but do so on Windows. Some have at least a small amount of Unix exposure, and most are comfortable at the Windows command shell.
These people struggle with:
- Basic shell operations. Despite being somewhat familiar with shells in general, most have trouble with Django's reliance on using the shell, and with
manage.py
commands in particular. They don't very much understand what something likepython manage.py startapp <app>
means; terms like "arguments" and "flags" in a shell context draw blank looks. They struggle with understanding how paths fit in withmanage.py
, often trying to runpython manage.py ...
from the wrong directory and getting confused with the errors about not findingmanage.py
- Environment variables. I completely avoid mentioning
DJANGO_SETTINGS_MODULE
because I've been unable to explain adequately what the "environ" is and how it interacts with programs they run. - Paths and general path name concepts, especially the distinction between absolute and relative paths. Something like setting
DATABASES[NAME]
correctly can take many attempts and trips to the shell to runpwd
to get correct. - The Python shell versus the Unix shell. Many try to type
python manage.py runserver
from the Python shell, orfrom django import ...
from the Unix shell.
People whose primary programming experience has been in Java or .NET often struggle with:
- Missing an IDE. Many Java/.NET developers struggle with the lack of things like file trees, a "run" button, etc. It's possible this is just a failure of my class (I teach Django without the use of an IDE, just a simple text editor and the shell); perhaps I should better meet these students where they are and help them use PyDev, PyCharm, or one of the other IDEs.
- Configuration in Python. Using Python to configure databases, logging, routing, etc. is a real shock to developers used to config files (most of them with matching IDE-provided config GUIs).
- Front-end vs. backend form handling: e.g. wanting to know if Django provides a data grid or client-side validation, then not quite understanding the idea of plugging something like jQuery into a Django site. I think especially .NET users are used to "heavier" widgets and things like auto-generated JS validation.
An interesting sidebar is that .NET programmers who've been exposed to ASP.NET MVC don't have any of these problems, and in fact are usually among the fastest learners. They often report that they find Django very similar to ASP.NET MVC, and have no trouble grasping the concepts.
That is, people used to do doing web development in static HTML, old-school CGI, PHP (without a framework) etc. These people struggle with:
- Routing in general. The idea that a URL doesn't correspond to a file is hard to explain; many try to load URLs like
/appname/views.py
or/appname/name_of_a_view_function
or something similar. - The template engine, especially template inheritance.
Again, not people new to programming, but people newly making the leap into web development. They have trouble with:
- HTML! Simple things like making links between views are difficult if you've never seen an
<a>
tag. They often say things like "it's not showing up" when they've missed a closing tag, put the entire markup into their<head>
, etc. - HTTP, in particular the distinction between GET data, POST data, headers, and metadata. Further, some developers have never been exposed to the concept of the request/response cycle, and find it difficult to understand what pieces are happening in the browser and what's happening on the server.
- The breakdown between Django, HTML, CSS, and JavaScript. I'll often get questions like "How do I make a popup in Django?".
A sizable minority of the people I've trained are transitioning from a strict DBA role to a more middle-tier app-and-database developer. Many of them are new to web development (see above) but on top of that they struggle with:
- Django's "model in Python" philosophy. These people have spent their careers nitpicking SQL, and they find the idea of having a framework generate it for them repugnant. They want to know how to map to an existing schema, and are especially put out by Django's lack of support for composite primary keys.
- ORMs in general (and Django's in particular). They want to know about performance, how to execute raw SQL, how to use views/stored procedures/triggers etc. They tend to be intensely suspicious of Django's query generation, and particularly the "automatic joining" which they see as inevitably fail-some.
They struggle with regexes :)
Sadly, there's also a bunch of stuff that the majority of my students continue to struggle with, despite my best efforts:
- "Too many files" — by the time we've started our second app, there are over a dozen files created between the project, models, views, and templates. Students struggle with finding where to put code, how to import stuff from other files, and how to find work they've already done.
- Too many files with the same name — questions like "which
models.py
does that go in?" are very common, as is a frustration about not being able to tell which of a couple same-named files are which in an editor window. - Too many settings — tasks like adding something to
INSTALLED_APPS
can take minutes while people sift through the file. (I suspect the new-on-truck simplified project layout should help with this.) - The admin versus views we write. Many try loading URLs like
/admin/<someroute>
instead of just/<someroute>/
. Perhaps this is a confusion about routing, but I think there's something specifically about the admin here because when I don't cover the admin most students don't have trouble with routing to their views. - Views versus templates, and particularly how a view is "tied" to a template, and how the template "knows" what data to render (e.g. they miss the linkage between
get_template()
, the context, and the template itself). - The overall "big picture" of how a request is actually handled and how everything fits together. They do OK with the URL -> view part, but fail after that. Most struggle to understand how model data gets into templates (for example, some think that the list of
Product
instances appear in theproduct_list.html
template because of the coincidental naming similarity). Most struggle to understand how templates link to views (see above). Most fail to distinguish between the things that the framework requires (URLs route to views, views return responses) and the things that are triggered by code in the views themselves (running queries, loading and rendering templates).
Very interesting stuff, thanks for compiling. I haven't taught nearly as much as you have, but I taught a one-semester web-dev university course using Python/Django, and a lot of these points had me nodding in recognition, particularly the very first section (shell and paths) and the "document-based" section (routing and template inheritance); most of my students had done some basic web work in PHP.
I notice (from the reference to
get_template
) that you teach people to write their own views using the CBV framework. Do you start right off with that, or do you start with simple function views first? Since you've been doing this 4-5 years, I wonder if you've noticed any difference in how quickly people "get" the request/response stuff and the view/context/template relationship since you've made that switch?I taught my course before the CBV framework existed, and I did spend an entire 3-hour class period on the request/response cycle in detail, but I found that students very quickly grasped the basic concept of a function view "request comes in, response goes out." The first views we did manually constructed an HttpResponse using a string, and only after that introduced template-rendering as an optional implementation detail of how a view might choose to construct the response content, and I didn't have any trouble with students not understanding that relationship. It seems like the CBV framework could really obfuscate all of that for newcomers; have you seen any correlation there?