Python/Django: First Impressions
I've started a brand-new codebase at work. With new code comes the possibility of a new language/platorm. What we really needed was speed; we don't know exactly what we want to build; we are going to have to iterate over many ideas quickly.
We had a long list of requirements. We wanted a simple, clean language. We needed to integrate with SOLR, but SOLR integrated with anything easily. We wanted fine-grain control of HTML output, so WSIWYG UI framewords like JSF and GWT were out. We wanted a popular platform, so there would be a good community to field questions.
Most importantly, we didn't want to limit our options down the road. Being potentially able to deploy on J2EE was huge. Ideally we would be able to import Java JARs, as well.
Both Ruby on Rails and Python/Django met our requirements. Django came out slightly ahead by having better documentation. Too much RoR info is still woefully out of date, or trapped in youtube videos.
Here are some quick thoughts on my first week programming Python/Django for an actual work project:
- Python itself is as nice a language as advertised.
- Hardly a single character is wasted in the source. You can do a lot in ten lines of Python, even if you're not calling out to libraries.
- lists, dictionaries, tuples, map() really help reduce your code.
def id_value_long(objs): result = [] for obj in objs: result.append((obj.id, str(obj)) return result # this is equivalent to id_value_long() def id_value(objs): return map(lambda obj: (obj.id, str(obj)), objs)
- You can make your code object oriented, or not. Mix and match. Note: private members are only by convention; the door is wide open to get at those.
- You have modern language features like aspect oriented programming (via decorators) and lambdas, implemented with clean syntax. They don't feel like in-elegant tack-ons.
- The standard library includes almost everything you could possibly want: reflection, regular expressions, dom parsing, web-services and unit testing.
- Django lets you do more with less code (sense a pattern here?)
- Real templating is worlds better than ColdFusion/JSP/PHP includes.
- You can hand-code your HTML for greater control, or use generic views for common cases.
class SearchForm(forms.Form): job = forms.ChoiceField(label="Source Job") query = forms.ChoiceField(label="Query Options") def __init__(self, jobs, queries, *args, **kwargs): super(SearchForm, self).__init__(*args, **kwargs) # ChoiceField needs id/value pairs, not full model objects self.fields["job"].choices = id_value(jobs) self.fields["query"].choices = id_value(queries) ... <FORM action="{% url results_link %}" method="get"> {{ form.as_p }} <INPUT type="submit" value="Search"/> </FORM>
- Just like RoR, you can auto-generate views from models. But in Django, these are by default relegated to an "admin" sub-site, which makes sense.
- Unlike RoR, Django doesn't manage scheme updates for you. Unless you want to blow away all your data every time, you need to write schema update scripts by hand. Fixtures can mitigate this in development, but not in production.
- Django doesn't do MVC, it does "MTV" (model, view, template). In my opinion, it's really MuTV, because the url mapper plays a controller-like role.