As you can see from the posts (one, two) I’ve always been a big Symfony fan. Symfony is really great, but my current favourite is clearly Django. I had to dive deep into python to use it, but it was well worth the effort.
Choosing Django:
Django has a few killer features which make it a better choice for many projects.
High Level Fields
As a starter there’s the usage of high level fields when describing your data model. This is best clarified by an example of a model definition in django:
class Author(models.Model): ip = models.IPAddressField() email = models.EmailField() company = models.ForeignKey(Company) picture = models.ImageField(upload_to='images/profile_pics', blank=True) homepage = models.URLField(verify_exists=True, blank=True)
Fields are specified by their purpose, such as Email, Url and Image. From this definition all subsequent logic such as form validation and file uploads are handled. The homepage field’s validation will even ping the url to see if it exists.
Read more: Creating Models (django project)
Form Handling
Starting with the knowledge that you have an email field you will often want a nice text input in your form with a regex to check if the email is valid. Django has all these standard use cases worked out for you. The following example clarifies this by using Django’s ModelForm. A model form is basically a normal Form class, with the fields pre-populated as one would expect it based on the given model.
#Form specification
class AuthorForm(ModelForm):
class Meta:
model = models.User
fields = ('ip','email','picture','homepage', 'company')
#Using the form in the view (controller in Symfony terminology)
form = AuthorForm(request.POST, instance=author_instance)
if request.method == 'POST':
if form.is_valid():
form.save()
return HttpResponseRedirect(request.path)
#In the template (view in Symfony terminology)
{{ uform.first_name.label_tag }}
: {{ uform.first_name }} {{ uform.first_name.errors }}
Django will display a file field for the image field, a text field for the url (with validation), a text input for the email field and a select box for the foreign key relation. Saving the result of the form to the database is as simple as calling save on the instance of the form. Writing custom widgets and field types is straightforward. Currently many localized fields such as a Dutch postal code Field and widgets are available. Symfony has been trying to emulate the Django newforms library. Unfortunately the syntax doesn’t seem very friendly. (Pity php doesn’t have metaclasses)
Read more: Forms (Django book)
Superb ORM
Probably the largest difference is caused by the ORM. In PHP both Propel and Doctrine are nice projects, but simply quite inadequate. The Django ORM is syntax heaven if you are coming from php. A small example:
#Find the first 5 authors which have a relation to a company #with the name YouTellMe (exact match) and site url that contains youtellme.nl Author.objects.filter(company__name = 'YouTellMe', company__site__icontains = 'youtellme.nl')[:5]
The possibilities of the standard Django ORM system are quite good. Your queries will be optimized into joins if you call select_related, many to many relations are supported and polymorphic keys are as well. The only part it fails at is query optimization in terms of column based lazy loading and support for complex relations. Fortunately you can fall back to using SQL alchemy, which is Python’s most prestigious ORM layer. SQL alchemy allows you exact query control for performance tuning and many more options you did not know you needed.
However it isn’t (yet, i hope) fully integrated into Django. It would really be great to see a tighter integration with SQL alchemy, but even the Django ORM strongly outperforms Doctrine and Propel.
Read more: DB api.
Python
You could see this both as an advantage or disadvantage. Discussing the differences between Python and PHP is probably best left for a later post. Suffice to say that I found my programming productivity to be substantially higher with Python compared to PHP. The disadvantage is a smaller number of available scripts, developers and hosts. If you are in a position in which you can choose, you really should give python a go. There must be a reason why YouTube and Google do ;)
Read more: Python in 10 Minutes
Speed
When arguing with my colleague about the choice of framework we conducted a speed test between Django and Symfony using Apache bench. At the time I was arguing in favor of Symfony. We compared a lightweight PHP framework, with Symfony and Django. Symfony was stripped down for performance and was only about 30% heavier compared to the lightweight framework. When comparing it to Django however, the results showed that Symfony was only able to handle half the load Django could. Using Python and Django seems to have a substantial effect on your server hardware requirements. (Note that these tests were only intended as an indication for internal usage. We didn’t test enough scenarios to be certain how the outcome would hold up on a live site. )
Symfony Still Rocks
When working with PHP Symfony is still an awesome framework. In many aspects it is even superior to Django. There are quite a few things Django could learn from Symfony:
Generic validation Classes and support for automatic js form validation
When using Symfony your javascript form validation is automatically generated. This is possible because of the usage of generic validation classes. In Django this would be hard to achieve since the validation system is not based on reusable classes.
A debug toolbar
![]()
One Symfony feature which I really miss in Django is the debug toolbar. Having an overview of your DB Queries, config settings, logging messages and caching information is very convenient. Especially for debugging a site with caching the caching indicators in Symfony are awesome. These caching indicators simply show which part of the page are taken from cache and which are freshly generated.
DRY templates
Symfony has a simple but very pleasant template tag called a component. A component tag calls a specified view and renders the corresponding template. The typical use case for this tag is sidebar with news items. You will want to show this sidebar on many pages, but you wouldn’t want to have to call that code inside each and every view which needs the sidebar. Doing so would clutter your view and hinder template caching. A nicer approach is to use a component template tag which calls the view responsible for retrieving the news from the database and rendering the sidebar template. This way of allowing the template to invoke code allows for DRY views and templates.
Clear Javascript and CSS management
In Django including a javascript or css file comes down to writing the respective tags in the template. In Symfony these things aren’t left to the template, but are set by the code. This allows for a few neat features. For instance the usage of an ajax utilizing template tag (helper in Symfony) will automatically ensure that prototype.js is loaded on that page. If you would set a textarea to rich, Symfony will automatically figure out you need TinyMCE to achieve the desired effect. Furthermore it allows for a general config file where you specify which assets should be loaded for a certain combination of application and view (in Django terminology). The main benefit of such an approach comes when you combine your css and javascript files and want to optimize the groupings. Here an example of the Symfony config:
// In the view.yml - comparable to settings.py
indexSuccess:
stylesheets: [mystyle1, mystyle2]
javascripts: [myscript]
[php]
// In the Action - Controller in Django terminology
$this->getResponse()->addStylesheet('mystyle1');
$this->getResponse()->addStylesheet('mystyle2');
$this->getResponse()->addJavascript('myscript');
// In the Template - The view in Django
Both are great, but Django more so
Having used both Django and Symfony I believe the two frameworks can learn a great deal from each other. Fortunately many people seem to experiment with a wide variety of frameworks (Including at least one delicious developer, version 3 of delicious maybe? ;)). Django in general has some excellent features, which make it a better choice for web development. If you are somehow bound to PHP, Symfony is still a good choice. The Django community is buzzing and active like no other and I look forward to posting on the various features.
If you didn’t try it yet:
django-project.com
djangobook.com
Note: Looking to hire Python and Javascript Coders
YouTellMe.nl is currently looking to hire Python and Javascript programmers in The Netherlands. Drop me an email at thierry [at] youtellme.com if you would like to know more or want to suggest someone for the job openings.







Dave Dash responded on 27 Aug 2008 at 8:13 pm #
Thierry,
I agree with you. They are both great frameworks, Django’s still better. I prefer python for much of my “we need a script that does…” type coding, and the use of it in a full web framework is very nice.
I was influenced by Fabien’s references to Django, so I pursued learning Python and starting to work on stuff Django.
PHP is quite heavily invested by Yahoo and a lot of companies. But Google does show that Python works wonders. The truth is you can make both do whatever you’d like … but I think most people who know both, have an easier time with Python.
I’ve been meaning to work on a toolbar for Django… I have some bits and pieces put together I should share them with you.
-dd
tschellenbach responded on 27 Aug 2008 at 8:28 pm #
Hey Dave,
Glad to hear that. I once started on a proper debug bar, but sort of left it partly unfinished, maybe we can glue some pieces together :)
Both languages indeed can build any site, but i would really miss Python’s list comprehension, functional programming fun, syntax, named arguments etc, etc
A PHP developer looks into Django « Fernando Correia’s Weblog responded on 28 Aug 2008 at 12:15 am #
[...] — fernandoacorreia @ 9:15 pm Tags: django, python, Web Thierry Schellenbach has published a very interesting article about his study for selecting a Web framework. A PHP developer that values the Symfony framework, [...]
David responded on 28 Aug 2008 at 1:03 am #
Hi Thierry,
When you mention Django’s shortcomings regarding “DRY templates”, I need to ask: have you read about extending the template engine and writing inclusion_tags?
You can read about that here: http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#inclusion-tags
You can actually execute any code you want inside of the tag (even retrieve data from the DB), and then pass whatever data you generate to a template to be rendered.
It has been said the Django documentation should tell you straight away that you need to learn how to extend the template engine, because you aren’t going very far with the included tags (although, from experience, I can say you can go _pretty_ far without learning how to extend).
Cheers.
Alex Gaynor responded on 28 Aug 2008 at 3:47 am #
FYI There is some great middlewear to add stuff like the dev toolbar you were talking about, just search django debug footer.
Also, if you want JS validation for your forms, I have a reusable app to add that validation using ajax, you can check it out at: http://code.google.com/p/django-ajax-validation/
alex responded on 28 Aug 2008 at 4:43 am #
the debut footer I was thinking of is django-logging and it is on google code.
Arthur responded on 28 Aug 2008 at 7:44 am #
I agree, I’ve also been using Symfony for a while and then later switched to Django—I’m a lot happier now although there are some things that I’m missing (like the Debug Toolbar). A lot of Symfony 1.1 is actually inspired by Django, for example the new Forms framework.
Massimo responded on 28 Aug 2008 at 8:08 am #
What’s your take about web2py? Did you try it?
Massimo responded on 28 Aug 2008 at 8:18 am #
Same code in web2py:
# in model db.py
db.define_table(’company’,SQLField(’name’))
db.define_table(’author’,
SQLField(’ip’,default=request.env.remote_addr),
SQLField(’email’,requires=IS_EMAIL()),
SQLField(’company’,db.company,requires=IS_IN_DB(db,’company.id’)),
SQLField(’picture’,'uoload’),
SQLField(’homepage’,requires=IS_URL()))
#in controller default.py
def index():
form=SQLFORM(db.author,fields= ['email','picture','homepage', 'company']
if form.accept(request.vars,session):
session.flash=’record inserted’
redirect(URL(r=request))
#in view default/index.html
{{=form}}
#example of select
db((db.company.name==’YouTellMe’)&(db.company.site.like(’%youtellme.nl%’))).select(limitby=0,5))
tschellenbach responded on 28 Aug 2008 at 9:24 am #
Thanks for the comments!
@dave
We’ve been writing quite a few custom tags and filters. I was missing something generic like the combine tag. Somehow I never looked into the inclusion tags. Fits the purpose very well, great :)
@alex
Ajax validation is indeed a good and easy option, a full client side solution would be nicer though.
Ill give the debug footer a try, looks good:
http://code.google.com/p/django-logging/wiki/Overview
Robert responded on 28 Aug 2008 at 9:35 am #
I would pick django because of Python. I can use Python in so many more scenarios than just the web frontier.
Nick Campbell responded on 28 Aug 2008 at 4:35 pm #
Regarding the DRY Templates…you can reuse templates. You actually have a great deal of flexibility with templates in Django.
You can both extend a “framing” type template and you can include “component” type templates.
http://www.djangobook.com/en/1.0/chapter04/
The bottom of this chapter details the “include” tag and Template inheritance. I recommend a read of this.
phpleo responded on 29 Aug 2008 at 3:00 am #
the i18n of symfony is more better than of django, because symfony use XLIFF and django gettext
links for 2008-08-28 « My Weblog responded on 29 Aug 2008 at 6:06 am #
[...] Mellow Morning » Django vs Symfony (tags: python php web) [...]
Mark Quezada responded on 29 Aug 2008 at 11:40 am #
Great post Thierry. I too have a lot of Symfony experience but am consistently drawn to Django. So many things are just cleaner. The only hurdle when developing sites for clients is the sheer ubiquity of PHP in the shared hosting landscape. Anyway, thanks for the post!
Lukas responded on 29 Aug 2008 at 12:10 pm #
In Doctrine you can also use “abstract datatypes” like email. I am hoping that after 1.0 the datatype handling will become even more flexible. Similar to the custom datatype system I implemented in PEAR::MDB2.
Then all of this stuff just needs to be connected from the Doctrine schema down into the form handling classes of symfony and you should be able to achieve similar features as you mentioned for Django, where you can control form validation from the model definitions.
Pedro Trindade » Blog Archive » Daily Digest for 2008-08-27 responded on 01 Sep 2008 at 12:45 pm #
[...] Django vs Symfony [...]
mozey responded on 08 Oct 2008 at 3:43 pm #
After reading our article shorter of two weeks ago, i decided to give django a try. And boy!, WaW. Being a java developer in the morning, python is much closer to home than php. But i never really questioned PHP because it is fast and effective.
I guess this was a time where i had to stop thinking like a getter donner and start thinking more like a mathematician in constant seek of the most elegant solution.
thanks for your post, :)
Thierry Schellenbach responded on 08 Oct 2008 at 7:40 pm #
Good to hear that :)
Bjorn responded on 20 Oct 2008 at 1:35 pm #
Hey Thierry,
On this github repository a Djang debug toolbar is available:
http://github.com/robhudson/django-debug-toolbar/tree/master
It more or less has the same features as Symfony’s debug toolbar ( although I have to say I haven’t used Symfony ).
Greets,
Bjorn.
Puneet responded on 28 Apr 2009 at 3:56 pm #
Nice, I think will go for django.
Mellow Morning " Django vs Symfony responded on 18 May 2009 at 11:42 pm #
[...] rest is here: Mellow Morning " Django vs Symfony Share and [...]
Drupal’s prominence is hurting the growth of the PHP frameworks, such as Symfony responded on 16 Nov 2009 at 12:15 am #
[...] versus framework, which would be more fair than the current framework versus CMS comparisons. (When the Django versus Symfony comparison is made, Symfony is at least able to hold its own, with at least a few areas where it is superior to [...]
nihimu responded on 28 Dec 2009 at 3:06 am #
As languages go I can say that after learning both by heart, only one of the feel like a real language. And its not PHP!
zoja responded on 05 Feb 2010 at 11:37 am #
I’m a great Symfony fan and i really found this article very interesting. You got me interested in looking further at Django. Seems like the perfect solution for big applications with high server load. Thanks for the the comparison :)