Wednesday, April 11th, 2012

Comparing Django to ASP.NET MVC

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.

Comment #1: Posted 2 years, 3 months ago by Erik Porter

You should try Razor for the view engine instead of Web Forms. Much cleaner. :)

-Erik
PM for Razor and MVC ;)

Comment #2: Posted 2 years, 3 months ago by Kevin Veroneau

Thank you for your comment Erik. The examples above are using Razor/ASP.NET syntax. Web Forms is when you use HTML tags to tell .NET where to run each server control, using the runat="server" attribute. -Kevin CIM-MSG II/MACS ECS ;)

Comment #3: Posted 2 years, 3 months ago by Joe

Great comparison article! I do have to defend Asp.net MVC just a little though. I agree that the Asp.net MVC view system is not as designer friendly, but this comes with a lot of added flexibility. You are able to create include files that you can bind directly to objects. I do enjoy this style, but I can understand if others do not. I have noticed that as Asp.net MVC as advanced it seems to be 'bloating' a bit. It has too many features now that I will most likely never use. This is why currently I would choose Django over Asp.net MVC for newer projects, even though I work in .Net technologies for my day job.

Comment #4: Posted 2 years, 3 months ago by Michael Christiansen

Hello, I always like reading articles like this that compare frameworks, it helps me get an idea for what else is out there and learn what I should expect from an MVC framework. So thank you for your post! I do think that the tutorial you were using was out of date, ASP.NET MVC is significantly closer to parity with Django than your initial assessment suggests (although I will definitely not dispute the fact that it seems to be in a constant state of catching up). I'll try and address some of your points in order without taking up too much space:

- The EntityFramework (Microsoft ORM) now supports what they call Code-First development. This allows you to define your models and let the framework create the database for you. The latest version will even generate migration code as you make changes to the model.
- You could define a link in MVC as: <a class="nav-link" href="@Url.Action("Contacts")">Contacts</a> which is much closer to your Django syntax, if that's what you preferred.
- Forms: You can accomplish something very similar to your django shorthand for the form above in ASP.NET MVC by marking up your model with Attributes then doing:
<% using (Html.BeginForm()){%>
@Html.EditorFor(Model)
<%}%>

I'd be the last person to try and argue that ASP.NET MVC is the best option out there, but it's far from the worst. I'll reserve that spot for Web Forms (zing!) And hey, it's open source now, doesn't that mean it gets to play with the cool kids? :)

Comment #5: Posted 2 years, 3 months ago by Simon Davy

You miss a lot of detail about the MVC platform. And I speak as a Django coder.

1. MVC has areas, which are similar to apps in Django land, although not quite as flexible.

2. The HTML action link is a bit of a strawman. Yes, the params can be confusing, but 99.9% of people will write it in VS, which will tell them the param order.

The point about designer friendliness is valid for that case, but django's template language is not that designer friendly generally (not compared to say, genshi). And the intellisense when writing Razor templates is very impressive. I personally have never needed for designers to write/edit html themselves, so it's not been an issue for me, and I think is fairly low down the issue list.

3. For forms, MVC has
Html.EditorForModel(m) which will do a whole form for a model object, and Html.EditorFor(m => m.prop) that will generate the input, label, and error message for a model field.

I think you've misrepresented MVC a bit here. Possibly following an old tutorial?

Don't get me wrong - I'd choose Django over MVC any day, but not for any of the reasons you mention. MS actually did a decent job with MVC (esp. v3+).

The reasons I would go with Django are a) python (+ecosystem) and b) the steaming quagmire of insanity that is Windows/IIS/ASP.NET (which MVC is still based on, under the hood)

But as a tool to write web apps, MVC is ok.

Comment #6: Posted 2 years, 3 months ago by Kevin Veroneau

Thank for for your new comments. The tutorial I referred to was on W3Schools.com, as it was formatted very nicely and was easy to understand.

@Micheal, it's good to know that the models can be now be mode in .Net now, the example you provide for form models, Django has as well, Forms and ModelForms in django are distinct, but share a similar API. In .Net can you create a form via a Class without having a database model bound to it? Django can work either with a Database model, or a custom Form object. A typical "ContactForm" doesn't usually get entered into a database, but is emailed to the webmaster. A search form, doesn't enter every user search into a database, it's just a simple form. The search form on this website was created using a Django form, and a special jQuery widget, which is bound to a database.

@Simon, thank you for your input. I may revisit this comparison in the future, when I have more time to dive into .Net and take it for a real test drive. I've attempted to use other frameworks, Web2py, web.py, bottle, Rails, CakePHP, but always seem to come back to Django in the end. There's just something about it...

Comment #7: Posted 2 years, 3 months ago by Hrvoje

I think it's not fair to judge some framework and compare it just by looking at some old tutorial. For most of the things that are mentioned here there're better ways to do it (speaking about asp.net mvc), and IMHO it's not so much different from Django. So, do better research next time ;)

Comment #8: Posted 2 years, 3 months ago by yuben

@Hrvoje +1

Comment #9: Posted 2 years, 3 months ago by tsimbalar

Thanks for the article !The comparison is a nice idea, but , as other commenters have mentioned, it is not completely fair, as of the latest version of ASP.NET MVC (ASP.NET MVC 3).

You may want to have a look at a more recent Tutorial such as : http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/getting-started-with-aspnet-mvc-3-cs/getting-started-with-mvc3-part1-cs . Among others, it addresses : models and validation, database/classes synchronization (although not specifically related to ASP.NET MVC).
Regarding reusability (widgets/forms), in ASP.NET MVC you would actually use Partial Views .

Another point to clarify is that the "models" you work with in ASP.NET MVC do not have to be linked to a database at all (in fact, this is considered bad practice to directly reference you DbModel in your views .. instead you would rely on lighter and more specialized ViewModels)

Nevertheless, this is completely right that ASP.NET MVC is still somehow trying to catch up with other Web Dev Frameworks, but it is going fast enough, and in the good direction.

Comment #10: Posted 1 year, 8 months ago by rodrigo

I have been user django for years, and now at work we are using .net mvc. .net mvc is closer to django than ohter microsoft techonology, but there are some issues related to internationalization, custom validations and others things that made .net mvc very though and not so automatic as django. In other words, .net mvc is an advance, but my opinion is that django is a step toward .net mvc

Comment #11: Posted 1 year, 8 months ago by Kevin Veroneau

rodrigo, I can agree with you there. I am thinking of taking another look at ASP.NET MVC, but sadly it's Linux server support is not very good. It works through Mono, but not everything was supported last time I checked. It's also difficult to give development time it's just deserves, if I'm not using the official development tools, Visual Studio in this case. Reason why I need to use a Linux server if I plan on trying this, is that I don't currently have a valid Windows license for this sort of development. I did this write up at my last job, where I was doing internal technical support for Microsoft. So I obviously had a Windows PC to play with there.

About Me

My Photo
Names Kevin, hugely into UNIX technologies, not just Linux. I've dabbled with the demons, played with the Sun, and now with the Penguins.




Kevin Veroneau Consulting Services
Do you require the services of a Django contractor? Do you need both a website and hosting services? Perhaps I can help.

This Month

If you like what you read, please consider donating to help with hosting costs, and to fund future books to review.

Python Powered | © 2012-2013 Kevin Veroneau