I recently decided to take a break from my own, somewhat-custom, python, web framework to play around with Django. I’ve been doing some contracting work, and the most popular web framework for Python seems to be Django. I decided that it would be worth my time to actually build something real using it (other than just a tutorial) to get some deeper familiarity with it (and maybe to lift ideas for PyBald).

There are a lot of things to like about Django, I’m saving those up for another post. This post is about how I just burned several hours trying to do a few things that seemed like they should be simple but turned out to be oddly frustrating at times. Im sure that part of this is just not being Django-expert-enough to have seen the obvious answers but the task at hand seemed simple enough: creating a user registration form for my application. (Yes I know there’s a user registration django app, but this seemed like a trivial task that should be easy with a good framework)

Custom Forms and Error Display

django_form.pngI started down the rabbit hole when I decided I didn’t really like the default way Django renders forms. There are a couple of options (as_table, as_p, as_ul), but whether displaying as a table, a list, or as <p> tags, the form layout didn’t match what I was used to. I know tables are often used for layout, but I really try and keep them for tabular data whenever possible. I also generally like to reserve <p> tags for actual text/content paragraphs and prefer <div> tags for logical divisions in a document. Might be nit-picky, but that seems more semantic to me.

Django_form_errors.png I could have lived with one of the default renderings but I found that I also wasn’t crazy about the way Django handles validation error display by default. Normally Django spits out a <ul> list of field errors with a css class of “errorlist” right above the offending field (or at the top of the form for general errors). Since the errors are only tied to the field by proximity, there’s no way to call out the offending field directly. With some styling, I could have made the error list clearer, but I still wasn’t crazy about this pattern.

When designing forms, I like to provide a small amount of usability by highlighting the error field in some way with an error style. At first I could find no way to do this with the default form rendering. Later I figured out that you can modify the widget tied to the field, but that seemed like putting too much display logic in the controller. It also seemed to require a lot of code repetition, putting this piece of code anywhere a form was instantiated and validated. I thought about creating a custom subclass of the form but that seemed heavy handed and I definitely didn’t want to alter Django internals. It also required playing with the two different kinds of field objects that come out of a form (more on that later).

for field in form:
     if field.errors:
        f.fields[field.name].widget.attrs['class'] = "field_error"
Adding error css to the widgets tied to fields. Not very DRY and not very clean in the controller / view (or template) separation

I wanted to keep this logic in the template which meant I needed to define my own form rendering. Easy enough, I just wrote my own generic form using the Django template language. I generally put input fields inside <div> tags. I also add a field_error css class to the divs that contain inputs with errors. That lets me define both special styles to highlight that section of the form and the offending fields directly ( with css like: .field_error input {} ), as well as use the error class as a key for special effects (like jQuery fades, etc…).

My initial custom form looked like this:

{# Include the hidden fields in the form #}
{% if form.non_field_errors %}
<div class="form_errors">
  {% for err in form.non_field_errors %}
  <div class="form_error_message">{{ err }}</div>
  {% endfor %}
</div>	
{% endif %}
{% for hidden in form.hidden_fields %}
   {{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
  <div {% if field.errors %}class="field_error"{% endif %}>
    {{ field.label_tag }}
    {{ field }}
    {% for err in field.errors %}
    <span class="error_message">{{ err }}</span>
    {% endfor %}
  </div>
{% endfor %}

Now from the Django documentation, they suggest creating a custom inclusion tag to render forms like this, but I held off on that for now (although it looks fairly easy). Since I’m generally producing one form per page (at the moment) I’m just using the Django include tag and including this form template into my page template where I need a form. So instead of {{ form.as_ul }} I’m using this: {% include base_form.html %} and assuming I’m using a context variable of form in the outer template (or using ‘with‘ to override form in the include as described in the docs).

Getting my own error displays working, with field highlighting I was happy with, was fairly easy. Right now validation errors appear as a series of spans next to the input field, but I’ll probably change this later.

Screen shot 2010-08-06 at 5.44.51 PM.png

Error css applied in the display logic. A simple yellow bg color styles allow me to highlight the error and the field.

Custom Form Validation

Next I started working with validation. Since this is for a custom user registration form, the first thing I need to do is validate that the username being registered is unique. Django has the concept of validation functions that can be passed to form fields. For my own web framework I’ve been using FormAlchemy, which has a fairly robust validation system and Django’s system is similar in some respects.

def validate_username_unique(value):
    '''Custom validator for user uniqueness.'''
    if User.objects.filter(username=value).exists():
        raise ValidationError(u'Sorry, someone already has that [...]')
 
class UserRegisterForm(forms.Form):
    # [... stuff ...]
    username = forms.CharField(validators=[validate_username_unique])
    # [... stuff ...]

Nice and clean, this is how I expect form validation to work.

Next I needed to confirm that the password and password confirm fields match. Validators only take one value input, so how do I validate that the fields match? Turns out Django’s validators aren’t up to the task so you have to plumb a little deeper into how it validates forms (as a note, Django’s docs are very good, but often times the difficulty is figuring out where in the docs something may or may not live).

To validate based on two fields you have to override the clean method on your subclassed form. When you want to flag validation errors on a particular field, you set the _errors['FIELDNAME'] on the form to flag the invalid fields. (remember that the clean method must return the cleaned_data member. That bit me in the rear for a while.)

class UserRegisterForm(forms.Form):
    # [...stuff...]
    password = forms.CharField(widget=forms.PasswordInput)
    password_confirm = forms.CharField(widget=forms.PasswordInput)
 
    def clean(self):
        '''Required custom validation for the form.'''
        super(forms.Form,self).clean()
        if 'password' in self.cleaned_data and 'password_confirm' in self.cleaned_data:
            if self.cleaned_data['password'] != self.cleaned_data['password_confirm']:
                self._errors['password'] = [u'Passwords must match.']
                self._errors['password_confirm'] = [u'Passwords must match.']
        return self.cleaned_data
validation of two dependent fields: the magic ‘clean’ method and the _error attribute

So now I have a form that checks that two fields are equal or else it flags a validation error. I had to add validation logic using two different mechanisms which seems a little messy but not too bad.

password_valid.png

Passwords must match!

Fieldsets

Lastly I decided I wanted to split my form inputs into fieldsets. Generally this is considered good practice, especially for usability and accesibility. The first option would be to just write out the form by hand, including the fieldsets, but that seemed like it could be brittle and not very django-like. Django also has some nice fieldset functionality for it’s admin app, so I assumed this would be trivially easy. Google searches seemed to turn up overly complex solutions for something that seems like it should be ‘built in’. There’s also a library ‘django form-utils’ that has fieldsets but I was trying to stick with generic Django forms.

This also highlights another issue I have, the way django defines ‘views’ and MVC. Much of the logic that in my definition of MVC would live in a controller, is delegated to something called a view in django. This view has a slight muddle of display logic and model manipulation. The template isn’t considered the view, but rather it’s own entitity, a presentation layer. It seems a little weird to me but I’m getting used to it.

This is where my frustration level really started to rise. I became very annoyed at the philosophical position that Django has taken that Django templates can’t run arbitrary python code. There are arguments for why this is/isn’t a good idea in a template system, but having come from using Mako for my templating system, this limitation started to drive me a little crazy.

My first impulse was to create a one-off custom form and use display logic in the template to change how things were laid out.

<fieldset><legend>Name</legend>
{% for fieldname in ('prefix','first_name','last_name') %}
{# render the fields for this fieldset #}
{% endfor %}
</fieldset>

Bzzzt.

TemplateSyntaxError at /register/user
Could not parse the remainder: '('prefix','first_name','last_name')' from
'('prefix','first_name','last_name')'

Django doesn’t allow you to create tuples or lists inside for blocks. The for tag only seems to work on iterators passed into the context. This seemed a little annoying to me since this logic seems ideally suited as display logic but it was forcing me to move the logic into the controller logic. I monkeyed with all sorts of ways to try and modify the display logic to no avail.

Then I decided to create an iterator that I could pass into the context so I could call out the individual field names.

    fieldset = ({'label':'Name','fields':('prefix','first_name','last_name')},)
    return render_to_response('registration/user_register.html',
                             {'form': f,'fieldset':fieldset}, 
                             context_instance=RequestContext(request))

Then in the template I tried using the names on the fields dictionary.

{% for set in fieldset %}
<fieldset><legend>{{ set.legend }}</legend>
{% for fieldname in set.fields %}
{{ form.fields[fieldname] }}
{% endfor %}
{% endfor %}
</fieldset>

Nope: TemplateSyntaxError. Again, the Django template language doesn’t like you accessing dictionary values by name in a variable block. Attributes seem OK, key values no. I’m not sure I like this “echoes of python” approach in the template language because it means learning another logic system rather than applying the full expressiveness of Python.

So, no dictionaries, I’ll pass the fields themselves in the fieldset as iterable objects.

fieldset = ({'legend':'Name',
             'fields':(f.fields['prefix'],
                       f.fields['first_name'],
                       f.fields['last_name'])},)
{% for set in fieldset %}
<fieldset><legend>{{ set.legend }}</legend>
{% for field in set.fields %}
<div>
{{ field }}
</div>
{% endfor %}
{% endfor %}
</fieldset>

Alright, no TemplateSyntaxErrors, but wait, what the…

Screen shot 2010-08-07 at 11.21.23 AM.png

It took a little experimentation and some object introspection but the issue here is that the form actually contains two representations of fields, bound and unbound. The code: for field in form.fields returns different objects than: for field in form.

Poking around the Django core I found that the iterator for a form instantiates BoundField objects from it’s internal fields and returns those. That’s what gets rendered as HTML. The docs do talk a bit about this distinction, but it’s mostly in passing and mentioning you have some additional methods on BoundFields.

Ok, so knowing I need to pass in an iterator, and that the iterator must return BoundFields to properly render in the template, I came up with this FieldSet class.

from django.forms.forms import BoundField
class FieldSet(object):
    def __init__(self,form,fields,legend='',cls=None):
        self.form = form
        self.legend = legend
        self.fields = fields
        self.cls = cls
 
    def __iter__(self):
        for name in self.fields:
            field = self.form.fields[name]
            yield BoundField(self.form, field, name)

So now in my ‘view’ code I instantiate FieldSets and pass them into a new form tempalte that knows what to do with them.

    fieldsets = (FieldSet(f, ('prefix','first_name','last_name'),
                        legend='Name',
                        cls="form_name_info"),
                FieldSet(f, ('username','email'), 
                        legend="User Info"),
                FieldSet(f, ('password','password_confirm'), 
                        legend="Password") )
 
    return render_to_response('registration/user_register.html',
                          {'form': f,'fieldsets':fieldsets},
                          context_instance=RequestContext(request))

Then I wrote an alternate form template with fieldsets to include when I want to use these fieldsets:

{# Include the hidden fields in the form #}
{% if form.non_field_errors %}
<div class="form_errors">
  {% for err in form.non_field_errors %}
  <div class="form_error_message">{{ err }}</div>
  {% endfor %}
</div>
{% endif %}
{% for hidden in form.hidden_fields %}
   {{ hidden }}
{% endfor %}
{% for set in fieldsets %}
<fieldset {% if set.cls %}class="{{ set.cls }}">{% endif %}
  <legend>{{ set.legend }}</legend>
  {% for field in set %}
    <div{% if field.errors %} class="error"{% endif %}>
      {{ field.label_tag }}
      {{ field }}
      {% for err in field.errors %}
      <span class="error_message">{{ err }}</span>
      {% endfor %}
    </div>
  {% endfor %}
{% endfor %}
</fieldset>

And finally: voila, a form with fieldsets generated on the fly, with custom rendering, custom validators, and styled error fields.

fieldsets_oof.png

Behold! a, well, rather unremarkable form.

Is this the best way to do it? I don’t know, but by the end I was just glad I got at least something to work. This was a first pass so I’m sure I’ll modify this over time (for example, it would probably make sense to create some kind of a FieldSet collection object that could render out a default fieldset for fields not tied to a FieldSet object). I found this day of frustrations definitely dampened my Django enthusiasm a bit. I’m sure as I understand and accept more of Django’s design (like no python code in templates) it will get easier to work with. My initial impressions of Django still stands, it makes getting up and running very fast and easy, but it can get thorny when you deviate from ‘the path’ at all.

{ 0 comments }

I’ve written before about Google’s strategy regarding Android but there seems to be a side effect to this strategy I hadn’t anticipated: the blistering speed with which they are innovating their core platform. The number of Android releases in such a short period of time, and the quality improvements in each release, has been nothing short of amazing. I had assumed iPhone experience parity would take much more time to achieve.

droid.png Google’s free (both as in speech and as in beer) approach has allowed them the latitude to focus completely on the core of their platform, to the exclusion of almost everything else. Since they have an odd upper-hand (handset makers really have no other choice) Google has almost completely ignored their needs and requirements. This has left handset makers (and customers) somewhat in the lurch, trying to keep up with the pace.

Android handset customers seem resigned to the fact that when they buy the latest and greatest phone, two months later something newer, shinier, and faster will be available. An interesting part of this approach is that since support is left almost completely to the phone makers, failures in the handset experience (platform fragmentation, slow speed of Android updates, etc…) seem to be blamed primarily on the hardware makers and carriers and not Google. Not being directly coupled to the market gives Google tremendous freedom to continue on their development trajectory.

I think this intentional rocket-ship paced speed of development is not sustainable. I predict that the handset makers (and customers) will begin to complain, and that the dreaded Android fragmentation problems will finally start to appear. The main problem won’t be between different capabilities among handsets (although that will be a problem), but by the fact that there will be a dozen different Android versions with different capabilities all in the market simultaneously.

I think Google’s strategy is to bring the Android experience close to the iPhone’s (it some ways it’s already there or superior) and then have the pace of development plateau. Not because Google won’t be capable of innovating at the same rate, but because market realities will inevitably begin to intrude into the process.

I think several things will conspire to slow down the rate of new versions. I predict Google will have to shift some resources to testing and compliance, creating some form of Google ‘certified Android compatible’ testing lab not unlike what Microsoft had to do with Windows. Handset makers will begin to resist the current pace of innovation by introducing new phones with versions of Android other than the latest. Carriers will continue to drag their feet updating their phones to the absolute latest Android. Unless the way handset makers and carriers do business fundamentally changes I think they will be unwilling to bear the cost of supporting and testing so many different versions of the platform. They will demand some ‘breathing room’ to allow their investment in the current version to pay off before moving to the next.

Another possibility is that Google will continue to innovate along the same curve and intentionally not care about the business realities of their hardware and network partners. Since Google primarily wants the ad revenue from Android on mobiles, maybe they will take a hands off approach and let the handset makers figure out how to make their business models conform to the new realities of Android. The only problem with that is the overall mobile phone experience could be compromised. If there’s one thing the iPhone still has going for it is it’s integrated experience.

{ 2 comments }

Here’s a secret: you are terrible at evaluating startup ideas

July 30, 2010

Here’s a secret: YOU are terrible at evaluating startup ideas. Yes, you. Now don’t get defensive, there’s a reason why I know you are terrible at it, you are a human being. So pardon me when, as an entrepreneur, I dismiss your description of my startup as a “dipshit company”

Read →

Steve Blank on startup business plan competitions

July 29, 2010

I stumbled across a post by Steve Blank of the Lean Startup movement and “Four Steps to the Epiphany” fame talking about business plan competitions: “No One Wins In Business Plan Competitions”. Steve’s argument is that business plan competitions are mapping the success methodology of big companies onto startups: operation and execution on known opportunities.

Read →

The Grazr widget will stop functioning

July 28, 2010

Sadly, Grazr.com is currently in the process of shutting down. Grazr the company has no official blog anymore so I’ve decided to write about the news. The truth is Grazr and the Grazr Widget have not been a focus of the company for a long time and it appears that the company can no longer justify the expense of keeping it running.

Read →

Boston Downtown

July 27, 2010

Took this picture the other day while we were driving around downtown. I love the light, the mixture of old and new architecture as well as the perspective. I’m not generally a good photographer but I thought this one turned out pretty cool. (Oh and it’s a pic with my new iPhone 4)

Read →

Something about startup competitions just doesn’t feel right

July 11, 2010

the process for competing in business plan or startup competitions is only tangentially related to what really needs to be done to launch a real, viable startup. I have a feeling that excelling in the environment of these kinds of competitions is, at best, inefficient use of time and effort and at worst, teaching potential entrepreneurs the wrong things to focus on for launching a company.

Read →

Startup Accelerator: Anything Goes Lab two week pilot

July 11, 2010

I’ve been trying to “hack the startup process” with a new kind of startup lab for a few months now. As part of the process of trying to launch TenZeroLab, I’ve been talking to a lot of people, pitching and describing the concepts behind it. Recently I started getting one particular piece of feedback: “Talk [...]

Read →

Tilt to Live – favorite iPhone game so far

June 27, 2010

Overall it’s a very high-quality game. The graphics are simple but satisfying. The music is fun. There are little tongue-in-cheek “Awards” you unlock for various game events. When you get enough awards, you unlock new weapons. Even though it’s accelerometer-based, the control isn’t twitchy or annoying. The game has enough twists and strategy to keep me trying that just… one… more… time…

Read →

Lackluster Startups Magazine

June 21, 2010

The magazine was pretty thin and didn’t really have much meat to it. If you’re just curious about startups (haven’t yet put any plans into action or done any research at all) this magazine might be somewhat interesting to you. The articles were OK, but not very informative or particularly inspiring. Part of the magazine was devoted to tips for getting started but these tips should be fairly well known to anyone who’s been even remotely interested in startups.

Read →