Is Django MVC doing it wrong?

I’ve just starting fooling around with Django (a Python web framework), and was looking to produce a form. Bear in mind that Django doesn’t really do MVC, but follows the philosophy – separation of logic, representation and appearance:

class BookForm(forms.Form):
    title = forms.CharField()

def BookView(request):
    form = BookForm()
    return render_to_response('book.html', {'form': form})

With boot.html containing (amongst other things):

<form action="" method="get">
{{ form.as_table }}
<input type="submit" value="Search" />
</form>

Which is great! MVC, separation of data, presentation and business logic. Now, how do you get a CSS class onto that title field? CSS, being the way of separating out the presentation part of a HTML page from the data that’s embedded in it? As above, but chuck it in as such:

class BookForm(forms.Form):
    title = forms.CharField(
        widget=forms.TextInput(attrs={'class':'title-field'}))

Seeing this crunched the gearbox in my mind. All that messy designer stuff, where they make things look nice, that’s worming it’s way into my business logic? Perhaps it’s not so wrong, as the business logic does indeed know that this is a title-field. But it doesn’t quite sit right with me. I’m not convinced it’s wrong, but if you were, you could instead do this in your CSS and HTML:

<style>
.title-field input {background:#ccC68f;}
</style>
<form action="" method="get">
<table>
<tr><td class="title-field"> {{ form.title }} </td></tr>
</table>
<input type="submit" value="Search" />
</form>

Which pretty much forces you to individually place fields — you get to specify the order of fields plus their individual CSS classes.

I’m not sure what the answer is here. Anyone care to enlighten this noob? Bear in mind that there’s a thing to magically tie a model to a form meaning you don’t even need to specify the fields in both the form and model, which you can’t use if you start tossing styles into each field.

2 thoughts on “Is Django MVC doing it wrong?

  1. glen

    It certainly looks wrong to me too. I’ve been working with ASP.NET MVC and it has a much better separation of the view and the controller. The way you have to specify the control type as a TextInput in the controller doesn’t seem right either. It means all of the views have to have the same fields on them, whether they’re a full web page or a tiny smartphone page. Seems restrictive.

  2. huxley

    You can use ModelForms and do ordering of fields and include HTML attributes.

    If you want to set a particular order, you define the fields you want to include in the order you want them to appear, in your ModelForm’s inner Meta class:

    http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#using-a-subset-of-fields-on-the-form

    You can also override any particular widget default in the ModelForms just like you can with regular forms. Pretty much everything can be overridden. And you can define different Form classes for different scenarios, so you can have different widgets for different devices and serve them as conditions in your views or URLs.

    By the way, in your example, you haven’t mixed CSS and HTML, you’ve only added an extra HTML attribute. IDs and classes are HTML attributes which can be used to connect a CSS style to a particular element, but there is no mixture of design and structure in your example.

    There are several approaches to MVC so two developers could disagree about the details but don’t confuse the Web’s separation of concerns with MVC, the HTML/CSS/Javascript separation of concerns is influenced by the MVC architectural pattern but it is a different thing.

Comments are closed.