Rails/Django Comparison
Rails/Django Comparison
n n
Reading
Development environments different: This was just a single trial. Really need:
● New Mac vs Old Windows laptop ● Multiple developers
● Multiple environments
● Deployment
● Maintainability
● No Atom/RSS feeds
Development practices:
● Didn’t do it the “best way”
Initial Expectations
Hours to Implement
30.00
25.00
HTML Prototype
20.00
15.00
10.00
5.00
0.00
Rails Django
Hours to Implement
30.00
25.00
Develop Test data
HTML Prototype
20.00
15.00
10.00
5.00
0.00
Rails Django
Hours to Implement
30.00
25.00
Project set up
Develop Test data
20.00 HTML Prototype
15.00
10.00
5.00
0.00
Rails Django
Hours to Implement
30.00
25.00
Models
Project set up
20.00 Develop Test data
HTML Prototype
15.00
10.00
5.00
0.00
Rails Django
Reader Book n m
Tag
1 1
n n
Reading
Hours to Implement
30.00
25.00
Models
Project set up
20.00 Develop Test data
HTML Prototype
15.00
10.00
5.00
0.00
Rails Django
Hours to Implement
30.00
25.00
Home page
Models
20.00 Project set up
Develop Test data
HTML Prototype
15.00
10.00
5.00
0.00
Rails Django
Hours to Implement
30.00
25.00
Basic pages
Home page
20.00 Models
Project set up
Develop Test data
15.00 HTML Prototype
10.00
5.00
0.00
Rails Django
Hours to Implement
30.00
25.00
Admin pages
Basic pages
20.00 Home page
Models
Project set up
15.00 Develop Test data
HTML Prototype
10.00
5.00
0.00
Rails Django
Hours to Implement
30.00
25.00
Amazon interface
Admin pages
20.00 Basic pages
Home page
Models
15.00 Project set up
Develop Test data
HTML Prototype
10.00
5.00
0.00
Rails Django
Hours to Implement
30.00
25.00
Data loading code
Amazon interface
20.00 Admin pages
Basic pages
Home page
15.00 Models
Project set up
Develop Test data
10.00 HTML Prototype
5.00
0.00
Rails Django
Hours to Implement
30.00
25.00
Test, tidy
Data loading code
20.00 Amazon interface
Admin pages
Basic pages
15.00 Home page
Models
Project set up
10.00 Develop Test data
HTML Prototype
5.00
0.00
Rails Django
Hours to Implement
30.00
26:46
25.00
Test, tidy
Data loading code
20.00 Amazon interface
Admin pages
16:36 Basic pages
15.00 Home page
Models
Project set up
10.00 Develop Test data
HTML Prototype
5.00
0.00
Rails Django
Hours to Implement
30.00
26:46
5.00
0.00
Rails Django
Hours to Implement - without Admin
30.00
25.00
Test, tidy
Data loading code
20.00 Amazon interface
18:21 Basic pages
Home page
15:39
15.00 Models
Project set up
Develop Test data
10.00 HTML Prototype
5.00
0.00
Rails Django
Lines of Code
Lines of Code
800
700
600 Model
500
400
300
200
100
0
Rails Django
Lines of Code
800
700
600 View/Controller
Model
500
400
300
200
100
0
Rails Django
Lines of Code
800
700
400
300
200
100
0
Rails Django
# Reader test data
Ben:
id: 1
username: benj72
fullname: Ben Askins
bio: Eats books for breakfast
Alan:
id: 2
username: agreen
fullname: Alan Green
bio: Fond of snakes
Fred:
id: 3
username: fred
fullname: Fred Wilkins
bio: Loves a good romantic thriller
readers.yml
Lines of Code
800
700
400
300
200
100
0
Rails Django
Lines of Code
800
700
600 Authentication
YAML data loading
500 View/Controller
Model
400
300
200
100
0
Rails Django
Lines of Code
800
700
300
200
100
0
Rails Django
Lines of Code
800
700
200
100
0
Rails Django
Lines of Code
800
700
600 Templates
HTML Helpers/
500 Template tags
Schema Migration
400 Authentication
YAML data loading
View/Controller
300
Model
200
100
0
Rails Django
●
Quicker
●
Slightly less code
●
Hand-coded admin
application
●
Concise
Browser Browser
Controller View
Model Model
Rails Django
Database Database
Browser Browser
Controller View
Model Model
Rails Django
Database Database
ActionController::Routing::Routes.draw # Some imports here
do |map| from hrproj.hr import views
/books/hitchhikers-guide-to-the-galaxy
URL Configuration
Browser Browser
Controller View
Model Model
Rails Django
Database Database
class BooksController < ApplicationController
end
Controller View
Model Model
Rails Django
Database Database
class ReadingOccasion(models.Model):
reader = models.ForeignKey(Reader)
book = models.ForeignKey(Book,
edit_inline=models.STACKED,
num_in_admin=1)
class Reading < ActiveRecord::Base finished = models.DateField(
belongs_to :book core=True)
belongs_to :reader reading_time = models.FloatField(
end max_digits=5,
decimal_places=2,
core=True,
blank=True)
notes = models.TextField(
maxlength=2000,
blank=True)
class ReadingOccasion(models.Model):
reader = models.ForeignKey(Reader)
book = models.ForeignKey(Book,
edit_inline=models.STACKED,
num_in_admin=1)
class Reading < ActiveRecord::Base finished = models.DateField(
belongs_to :book core=True)
belongs_to :reader reading_time = models.FloatField(
end max_digits=5,
decimal_places=2,
core=True,
blank=True)
notes = models.TextField(
maxlength=2000,
blank=True)
Schema evolution
class CreateReadings < ActiveRecord::Migration
def self.up
create_table :readings do |t|
t.column "book_id", :integer
t.column "reader_id", :integer
t.column "date_read", :datetime
t.column "reading_time", :integer
t.column "notes", :text
end
end
def self.down
drop_table :readings
end
end
Schema is Versioned
● Drop database tables
● Re-create tables
manage.py syncdb
python yaml/load_data.py
Django DB evolution
Browser Browser
Controller View
Model Model
Rails Django
Database Database
books/show.rhtml:
<%= render :partial => 'readings/list',
:locals => {:key_field => "Reader"} %>
readings/_list.rhtml: book_detail.html:
<tbody> <tbody>
<%= render :partial => 'readings/reading', {% for ro in readingoccasion_list %}
:collection => @readings, <tr>
:locals => {:key_field => key_field} %> <td class="name_col">
</tbody> <a href="{{ ro.reader.get_absolute_url }}">
{{ ro.reader.name }}
readings/_reading.rhtml: </a>
<tr> </td>
<td class="name_col"> <td class="date_col">
<% if key_field == "Book" %> {{ ro.finished|date:"j M Y" }}
<%= link_to reading.book.title, </td>
book_url(reading.book) %> <td class="num_col">
<% else %> {{ ro.reading_time }}
<%= link_to reading.reader.fullname, </td>
reader_url(reading.reader) %> <td>{% firstof ro.notes "-" %}</td>
<% end %> </tr>
</td> {% endfor %}
<td class="date_col"> </tbody>
<%= reading.date_read_for_display %>
</td>
<td class="num_col">
<%= reading.reading_time %>
</td>
<td><%= reading.notes %></td>
</tr>
View / Template
readers/show.rhtml:
<%= render :partial => 'readings/list',
:locals => { :key_field => "Book" } %>
reader_detail.html:
<tbody>
{% for ro in readingoccasion_list %}
<tr>
<td class="name_col">
<a href="{{ ro.book.get_absolute_url }}">
{{ ro.book.title }}
</a>
</td>
<td class="date_col">
{{ ro.finished|date:"j M Y" }}
</td>
<td class="num_col">
{{ ro.reading_time }}
</td>
<td>{% firstof ro.notes "-" %}</td>
</tr>
{% endfor %}
</tbody>
View / Template
And the other bits
● Can save a lot of time
● Good looking result
● Does simple CRUD quite well
but...
● Only does simple CRUD
● Only does simple relationships
● Security not fine-grained
● Not intended for public-facing pages
AJAX
Books on Amazon
11
10
9
8
7
6
5
4
3
2
1
0
Rails
Django
Jobs on seek.com.au
120
110
100
90
80
70
60
50
40
30
20
10
0
Ruby Ruby on Rails Python Django
● Began Oct 2003 ● Began Fall 2003
● DHH ● Adrian and Simon
– in reaction to PHP – “ditched” PHP
● Extracted from ● Extracted from
Basecamp ljworld.com
● Released: July 2004 ● Released: July 2005
● 1.0 shipped Dec 2005 ● 1.0 not yet shipped
– Latest is 1.1.6 – Latest is 0.95
History
Conclusion
Already using Rails?
Already using Rails?
Already using Django?
Already using Django?
Already know Ruby?
Already know Ruby?
Already know Python?
Already know Python?
Private admin pages?
Private admin pages?
Simple
AJAX?
Simple
AJAX?
Non-programming
web designers?
Non-programming
web designers?
Evolving Schema?
Evolving Schema?
Maturity
Maturity – product,
community, and market
Maturity – product,
community, and market
Concise or Explict?
Concise Explicit
Still can’t choose?
Thanks!
● Photos
– Sad puppy:
http://www.flickr.com/photos/sookie/108356632/
● Software
– David A. Wheeler’s Sloccount
● http://www.dwheeler.com/sloccount/
– HTML Template by Andreas Viklund
● All of the paper reviewers
● Our bosses:
– Cirrus Technologies
– Karen Askins
With thanks to
● “The Builders of Basecamp”
– http://www.oreillynet.com/pub/a/network/2005/03/10/base
● Snakes and Rubies presentation
– http://video.google.com/videoplay?docid=2939556954580
● Django FAQ
– http://www.djangoproject.com/documentation/faq/
Lots of interest in these two frameworks
Different in others
Why Comparing?
This is some Ruby code This is some Python code
Bonus Material
def standard_view(request, queryset, template_name,
template_object_name, **extra_context):
""" Wrapper around the object_list generic view.
"""
return object_list(request,
queryset=queryset,
allow_empty=True,
template_name=template_name,
template_object_name=template_object_name,
page=get_page(request),
paginate_by=PAGE_SIZE,
extra_context=extra_context)
def get_page(request):
""" Determines the current page number.
"""
return int(request.GET.get('page', 1))
standard_view
Hours to Implement
30.00
20:40
25.00
Test, tidy
Data loading code
20.00 Amazon interface
Admin pages
10:30 Basic pages
15.00 Home page
Models
Project set up
10.00 Develop Test data
HTML Prototype
5.00
0.00
Rails Django