A Rails/Django Comparison
by Ben Askins and Alan Green

This work is licensed under the Creative
Commons            Attrib...
Rails vs. Django
We wrote the same application twice
Reader                 Book   n   m
                                      Tag
    1              1

          n   n



   ...
Development environments different:            This was just a single trial. Really need:
  ● New Mac vs Old Windows lapto...
Some Data
Plan
$1 000 000
US$1 000 000
Time to
Implement
“You don’t understand
“This’ll be easy I’ll whip it
                                the power of the built-in
  up in a we...
Hours to Implement
30.00


25.00
                                      HTML Prototype


20.00


15.00


10.00


 5.00


 0...
Hours to Implement
30.00


25.00
                                      Develop Test data
                                 ...
Hours to Implement
30.00


25.00
                                      Project set up
                                    ...
Hours to Implement
30.00


25.00
                                      Models
                                      Projec...
Reader                 Book   n   m
                                      Tag
    1              1

          n   n



   ...
Hours to Implement
30.00


25.00
                                      Models
                                      Projec...
Hours to Implement
30.00


25.00
                                      Home page
                                      Mod...
Hours to Implement
30.00


25.00
                                      Basic pages
                                      H...
Hours to Implement
30.00


25.00
                                      Admin pages
                                      B...
Hours to Implement
30.00


25.00
                                      Amazon interface
                                  ...
Hours to Implement
30.00


25.00
                                      Data loading code
                                 ...
Hours to Implement
30.00


25.00
                                      Test, tidy
                                      Da...
Hours to Implement
30.00
                   26:46

25.00
                                            Test, tidy
          ...
Hours to Implement
30.00
                   26:46

25.00                  Admin Pages
                                    ...
Hours to Implement - without Admin
30.00


25.00
                                              Test, tidy
                ...
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

2...
Lines of Code
800

700

600                           YAML data loading
                              View/Controller
500 ...
# Reader test data
Ben:
  id: 1
  username: benj72
  fullname: Ben Askins
  bio: Eats books for breakfast
Alan:
  id: 2
  ...
Lines of Code
800

700

600                           YAML data loading
                              View/Controller
500 ...
Lines of Code
800

700

600                           Authentication
                              YAML data loading
500  ...
Lines of Code
800

700

600                           Schema Migration
                              Authentication
500   ...
Lines of Code
800

700

600                           HTML Helpers/
                              Template tags
500       ...
Lines of Code
800

700

600                           Templates
                              HTML Helpers/
500           ...
●
                           Quicker
                       ●
                           Slightly less code
●
    Hand-cod...
Browser                             Browser




    Web Server                          Web Server




Routes             ...
Browser                             Browser




    Web Server                          Web Server




Routes             ...
ActionController::Routing::Routes.draw   # Some imports here
    do |map|                             from hrproj.hr impor...
Browser                             Browser




    Web Server                          Web Server




Routes             ...
class BooksController < ApplicationController

  before_filter :find_book                      def book_detail(request, sl...
Browser                             Browser




    Web Server                          Web Server




Routes             ...
class ReadingOccasion(models.Model):
                                       reader = models.ForeignKey(Reader)
           ...
class ReadingOccasion(models.Model):
                                       reader = models.ForeignKey(Reader)
           ...
Schema evolution
class CreateReadings < ActiveRecord::Migration
  def self.up
    create_table :readings do |t|
      t.column "book_id", :...
●   Drop database tables
●   Re-create tables
         manage.py syncdb
         python yaml/load_data.py

●   In producti...
Browser                             Browser




    Web Server                          Web Server




Routes             ...
books/show.rhtml:
<%= render :partial => 'readings/list',
    :locals => {:key_field => "Reader"} %>

readings/_list.rhtml...
readers/show.rhtml:
<%= render :partial => 'readings/list',
    :locals => { :key_field => "Book" } %>

                  ...
And the other bits
●   Can save a lot of time
●   Good looking result
●   Does simple CRUD quite well
but...
●   Only does simple CRUD
●   On...
page.visual_effect :fade, dom_id(@tag)
page.replace_html “feedback”, “Tag Deleted”
page.visual_effect :appear, “feedback”,...
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...
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...
●   “The Builders of Basecamp”
    –   http://www.oreillynet.com/pub/a/network/2005/03/10/base
●   Snakes and Rubies prese...
Lots of interest in these two frameworks

         Similar in some ways

          Different in others

      How to choos...
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...
Hours to Implement
30.00
                   20:40

25.00
                                            Test, tidy
          ...
Rails vs Django Study Presentation
Rails vs Django Study Presentation
Rails vs Django Study Presentation
Rails vs Django Study Presentation
Rails vs Django Study Presentation
Rails vs Django Study Presentation
Rails vs Django Study Presentation
Rails vs Django Study Presentation
Rails vs Django Study Presentation
Rails vs Django Study Presentation
Rails vs Django Study Presentation
Rails vs Django Study Presentation
Upcoming SlideShare
Loading in …5
×

Rails vs Django Study Presentation

6,978 views

Published on

Ruby on Rails ("Rails") is the dominant web programming framework for Ruby and, even outside the
Ruby community, is considered the epitome of the latest generation of high-productivity, open source
web development tools. Django is one of many competing web development frameworks for Python. It
is notable, first, for being highly regarded amongst Python programmers, and second, for being one of
the few of the new generation of frameworks that does not ape Ruby on Rails. Both Rails and Django
claim greatly enhanced productivity, compared with more traditional web development frameworks.
In this paper, we compare the two frameworks from the point of view of a developer attempting to
choose one of the two frameworks for a new project.

Published in: Technology
0 Comments
8 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,978
On SlideShare
0
From Embeds
0
Number of Embeds
96
Actions
Shares
0
Downloads
56
Comments
0
Likes
8
Embeds 0
No embeds

No notes for slide

Rails vs Django Study Presentation

  1. 1. A Rails/Django Comparison by Ben Askins and Alan Green This work is licensed under the Creative Commons Attribution-NonCommercial- ShareAlike 2.5 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.5/ or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA. The original version of this presentation is available at http://3columns.net/habitual/docs/Pres2.odp
  2. 2. Rails vs. Django
  3. 3. We wrote the same application twice
  4. 4. Reader Book n m Tag 1 1 n n Reading
  5. 5. Development environments different: This was just a single trial. Really need: ● New Mac vs Old Windows laptop ● Multiple developers ● Central Coast vs Cityrail ● Multiple applications ● Multiple environments “Multiple” means “statistically significant” Developer skill level: ● Not identical ● Too advanced to be called ‘beginners’ ● Insufficiently advanced to be ‘typical’ Didn’t consider: ● Performance ● Deployment ● Maintainability LOC and time-to-implement ● Enterprise-friendliness measurements are stupid: ● Not transferable to other developers ● Only rough indicator of complexity Unrepresentative example application: ● Too few pages ● No Atom/RSS feeds ● No public data entry Development practices: ● Didn’t do it the “best way” ● Older versions of Rails and Django ● Didn’t use this or that helpful third party feature Part-time development – start-stop effect and gaps between sessions
  6. 6. Some Data
  7. 7. Plan
  8. 8. $1 000 000
  9. 9. US$1 000 000
  10. 10. Time to Implement
  11. 11. “You don’t understand “This’ll be easy I’ll whip it the power of the built-in up in a weekend.” admin application.” Initial Expectations
  12. 12. Hours to Implement 30.00 25.00 HTML Prototype 20.00 15.00 10.00 5.00 0.00 Rails  Django
  13. 13. Hours to Implement 30.00 25.00 Develop Test data HTML Prototype 20.00 15.00 10.00 5.00 0.00 Rails  Django
  14. 14. 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
  15. 15. 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
  16. 16. Reader Book n m Tag 1 1 n n Reading
  17. 17. 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
  18. 18. 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
  19. 19. 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
  20. 20. 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
  21. 21. 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
  22. 22. 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
  23. 23. 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
  24. 24. 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
  25. 25. Hours to Implement 30.00 26:46 25.00 Admin Pages 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
  26. 26. 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
  27. 27. Lines of Code
  28. 28. Lines of Code 800 700 600 Model 500 400 300 200 100 0 Rails Django
  29. 29. Lines of Code 800 700 600 View/Controller Model 500 400 300 200 100 0 Rails Django
  30. 30. Lines of Code 800 700 600 YAML data loading View/Controller 500 Model 400 300 200 100 0 Rails Django
  31. 31. # 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
  32. 32. Lines of Code 800 700 600 YAML data loading View/Controller 500 Model 400 300 200 100 0 Rails Django
  33. 33. Lines of Code 800 700 600 Authentication YAML data loading 500 View/Controller Model 400 300 200 100 0 Rails Django
  34. 34. Lines of Code 800 700 600 Schema Migration Authentication 500 YAML data loading View/Controller 400 Model 300 200 100 0 Rails Django
  35. 35. Lines of Code 800 700 600 HTML Helpers/ Template tags 500 Schema Migration Authentication 400 YAML data loading View/Controller Model 300 200 100 0 Rails Django
  36. 36. 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
  37. 37. ● Quicker ● Slightly less code ● Hand-coded admin application ● Concise
  38. 38. Browser Browser Web Server Web Server Routes View urls.py Template Controller View Model Model Rails Django Database Database
  39. 39. Browser Browser Web Server Web Server Routes View urls.py Template Controller View Model Model Rails Django Database Database
  40. 40. ActionController::Routing::Routes.draw # Some imports here do |map| from hrproj.hr import views map.connect '', :controller => "home" urlpatterns = patterns('', # restful resources (r'^$', views.index), map.resources :books do |books| books.resources :readings (r'^readers/$', views.reader_list), end (r'^tags/$', views.tag_list), (r'^books/$', views.book_list), map.resources :readers do |readers| readers.resources :reader_images (r'^readers/(?P<username>.*)/$', end views.reader_detail), (r'^tags/(?P<slug>.*)/$', map.resources :tags views.tag_detail), end (r'^books/(?P<slug>.*)/$', views.book_detail), ) /books/hitchhikers-guide-to-the-galaxy URL Configuration
  41. 41. Browser Browser Web Server Web Server Routes View urls.py Template Controller View Model Model Rails Django Database Database
  42. 42. class BooksController < ApplicationController before_filter :find_book def book_detail(request, slug): book = get_object_or_404(Book, slug=slug) def show queryset = ReadingOccasion.objects @reading_paginator, @readings = paginate .filter(book=book) :readings, .order_by('finished') :conditions => ["book_id = ?", return standard_view( @book.id] request, queryset, end 'book_detail.html', 'readingoccasion', private book=book) def find_book @book = Book.find_by_title(params[:id]) end end Controller / View Function
  43. 43. Browser Browser Web Server Web Server Routes View urls.py Template Controller View Model Model Rails Django Database Database
  44. 44. 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)
  45. 45. 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)
  46. 46. Schema evolution
  47. 47. 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
  48. 48. ● Drop database tables ● Re-create tables manage.py syncdb python yaml/load_data.py ● In production, you write migration DDL by hand Django DB evolution
  49. 49. Browser Browser Web Server Web Server Routes View urls.py Template Controller View Model Model Rails Django Database Database
  50. 50. 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
  51. 51. 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
  52. 52. And the other bits
  53. 53. ● 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 Django Admin application
  54. 54. page.visual_effect :fade, dom_id(@tag) page.replace_html “feedback”, “Tag Deleted” page.visual_effect :appear, “feedback”, :queue => :end page.visual_effect :fade, “feedback”, :queue => :end AJAX
  55. 55. Books on Amazon 11 10 9 8 7 6 5 4 3 2 1 0 Rails Django
  56. 56. Jobs on seek.com.au 120 110 100 90 80 70 60 50 40 30 20 10 0 Ruby Ruby on Rails Python Django
  57. 57. ● 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
  58. 58. Conclusion
  59. 59. Already using Rails?
  60. 60. Already using Rails?
  61. 61. Already using Django?
  62. 62. Already using Django?
  63. 63. Already know Ruby?
  64. 64. Already know Ruby?
  65. 65. Already know Python?
  66. 66. Already know Python?
  67. 67. Private admin pages?
  68. 68. Private admin pages?
  69. 69. Simple AJAX?
  70. 70. Simple AJAX?
  71. 71. Non-programming web designers?
  72. 72. Non-programming web designers?
  73. 73. Evolving Schema?
  74. 74. Evolving Schema?
  75. 75. Maturity
  76. 76. Maturity – product, community, and market
  77. 77. Maturity – product, community, and market
  78. 78. Concise or Explict?
  79. 79. Concise Explicit
  80. 80. Still can’t choose?
  81. 81. Thanks!
  82. 82. ● 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
  83. 83. ● “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/
  84. 84. Lots of interest in these two frameworks Similar in some ways Different in others How to choose between them? Why Comparing?
  85. 85. This is some Ruby code This is some Python code
  86. 86. Bonus Material
  87. 87. 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
  88. 88. 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

×