I decided to go through a short tutorial on how to build a basic movie database using ASP.NET's MVC framework. As I am reading it, I can already see the differences between both frameworks.
The first thing I notice, is that a default project layout in ASP.NET does not have a concept of individual apps, which can be easily used between multiple projects. The folder structure is geared more towards a monolithic application, a single folder contains all the models, controllers, and views. There is no separation of apps. This can be a mixed bag, depending on the kind of programmer you are, personally I like to keep my ideas separate, and easily usable among several projects.
The next thing I notice is the way the models and databases are built. Like most frameworks on the market, you need to specifically create the database table, then separately create a model in your application to reference the database table. I prefer Django's method, all I need to do is tell Django where my database is(connection URI info), and build my entire database in the models.py for my particular app. Once I'm ready to create the tables in the database, all I need to run is manage.py syncdb, or if I'm using South, it will differ a little, but there is still minimal database work. It just works, a term Microsoft has been struggling with since they pushed out Windows '95. Django does indeed just work.
The template systems also differ, depending on how you build the templates in ASP.NET. The tutorial I am reading through uses Razor. It seems to embed actual source code within the template... If you are developing an application where you have a separate HTML/CSS designer, this is no good. A web designer should not need to know how to program or what objects are and how to embed links into the page. A web designer's purpose is to create a nicely polished website, with perhaps some basic logic or special tags. In Django we can add a URL link to a page using this:
<a class="nav-link" href="{% url "contact-list" %}">Contacts</a>
For a designer to look at the above code, he/she can easily learn and understand what it does. It creates a URL to a specific page in the app called contact-list. Here is the same code in Razor:
@Html.ActionLink("Contacts", "Contacts")
A web designer sees this, he will wonder how he can easily add a link using his fancy WYSIWYG editor, and which parameter is actually the target and which shows what is displayed to the visitor? This format is not very web designer friendly, as it cannot be easily integrated into WYSIWYG editors. The Django alternative can be easily put into the link href using any editor, and it won't complain.
Finally we come to forms, not web forms, that's a completely separate platform(talk about confusing). ASP.NET MVC does not have a Form class which can be called into any template with ease. Instead the form is created directly in the HTML, along with the validation information. This is very messy coding, and does not properly separate the components for easy debugging and moving around. This also destroys the DRY principle, DRY stands for Don't repeat yourself. In Django, if you wanted to use a form multiple times, or in multiple applications, is literally easy-peasy. You create a simple straightforward class, and can either base the class of an existing database model, or write the fields from scratch. Once the class is done, sent it off to the template as a context to be rendered. Django offers many rendering methods, to make it really easy to test forms and fine tune them. Here is a simple form in Django:
from django import forms
from django.forms.widgets import PasswordInput, Textarea
class ContactForm(forms.Form):
first_name = forms.CharField()
last_name = forms.CharField()
password = forms.CharField(widget=PasswordInput)
confirm_password = forms.CharField(widget=PasswordInput)
profile = forms.CharField(widget=Textarea(attrs={'cols':'60','rows':'10'}))
newsletter = forms.BooleanField(label='Receive Newsletter?', required=False)
def clean_confirm_password(self):
password1 = self.cleaned_data.get("password", "")
password2 = self.cleaned_data["confirm_password"]
if password1 != password2:
raise forms.ValidationError("The two password fields didn't match.")
return password2
This class, can be added into any other application you create to create the same functionality. The class also contains the validation of the 2 password fields. You may notice the usage of widgets, this allows one to further customize and reuse widgets between many apps with ease. Here is the simple template which can render the above:
<form method="post">
{{form.as_p}}
<input type="submit" value="Register" />
</form>
That's all there is to it, even a web designer should be-able to understand what it does. If one does not pass as_p to form, it will render as a table. Just for kicks, here is the Django view which would send the form out as a context and check for validation errors:
def contact_us(req):
if req.method == 'POST':
form = ContactForm(req.POST)
if form.is_valid():
# No validation errors.
pass
else:
form = ContactForm()
return render(req, "contact_form.html", {'form':form})
Pretty straightforward function. Here is the same contact form in ASP.NET:
<%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>
<% using (Html.BeginForm()){%>
<p>
<label for="FirstName">First Name:</label>
<%= Html.TextBox("FirstName") %>
<%= Html.ValidationMessage("FirstName", "*") %>
</p>
<p>
<label for="LastName">Last Name:</label>
<%= Html.TextBox("LastName") %>
<%= Html.ValidationMessage("LastName", "*") %>
</p>
<p>
<label for="Password">Password:</label>
<%= Html.Password("Password") %>
<%= Html.ValidationMessage("Password", "*") %>
</p>
<p>
<label for="Password">Confirm Password:</label>
<%= Html.Password("ConfirmPassword") %>
<%= Html.ValidationMessage("ConfirmPassword", "*") %>
</p>
<p>
<label for="Profile">Profile:</label>
<%= Html.TextArea("Profile", new {cols=60, rows=10})%>
</p>
<p>
<%= Html.CheckBox("ReceiveNewsletter") %>
<label for="ReceiveNewsletter" style="display:inline">Receive Newsletter?</label>
</p>
<p>
<input type="submit" value="Register" />
</p>
<%}%>
This is pretty messy compared to the Django code, and this code doesn't actual validate much, besides the point that all fields are filled in. If you are a web designer reading this, which one of these would you prefer to work with? Remember the Django code can be expanded to this:
<form>
<p>
<label for="FirstName">First Name:</label>
{{form.first_name}}
{{form.first_name.errors}}
</p>
<p>
<label for="LastName">Last Name:</label>
{{form.last_name}}
{{form.last_name.errors}}
</p>
<p>
<label for="Password">Password:</label>
{{form.password}}
{{form.password.errors}}
</p>
<p>
<label for="Password">Confirm Password:</label>
{{form.confirm_password}}
{{form.confirm_password.errors}}
</p>
<p>
<label for="Profile">Profile:</label>
{{form.profile}}
</p>
<p>
{{form.newsletter}}
<label for="ReceiveNewsletter" style="display:inline">Receive Newsletter?</label>
</p>
<p>
<input type="submit" value="Register" />
</p>
</form>
Django is built from the ground up for customization, as you can see. You can even sub-class the form to alter it for a different purpose. Django takes full advantage of object-oriented programming. My next comparing article will be about Web Forms, which is another development component of ASP.NET. I may not be-able to compare it with Django, and if not, I will see what in the Python world will compare with Web Forms.
I will let the reader decide which framework they will choose for their next MVC/MTV web project.
