Rails/django Comparison

  • Uploaded by: Pascal Van Hecke
  • 0
  • 0
  • August 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Rails/django Comparison as PDF for free.

More details

  • Words: 1,752
  • Pages: 100
A Rails/Django Comparison by Ben Askins and Alan Green This work is licensed under the Creative Commons Attribution-NonCommercialShareAlike 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

Rails vs. Django

We wrote the same application twice

Reader

Book 1

1 n

n

Reading

n

m

Tag

Development environments different: ● New Mac vs Old Windows laptop ● Central Coast vs Cityrail

This was just a single trial. Really need: ● Multiple developers ● Multiple applications ● Multiple environments “Multiple” means “statistically significant”

Developer skill level: ● Not identical ● Too advanced to be called ‘beginners’ ● Insufficiently advanced to be ‘typical’

LOC and time-to-implement measurements are stupid: ● Not transferable to other developers ● Only rough indicator of complexity

Didn’t consider: ● Performance ● Deployment ● Maintainability ● Enterprise-friendliness 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

Some Data

Plan

$1 000 000

US$1 000 000

Time to Implement

“This’ll be easy I’ll whip it up in a weekend.”

“You don’t understand the power of the built-in admin application.”

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 HTML Prototype

20.00

15.00

10.00

5.00

0.00

Rails 

Django

Hours to Implement 30.00

25.00 Models Project set up Develop Test data HTML Prototype

20.00

15.00

10.00

5.00

0.00

Rails 

Django

Reader

Book 1

1 n

n

Reading

n

m

Tag

Hours to Implement 30.00

25.00 Models Project set up Develop Test data HTML Prototype

20.00

15.00

10.00

5.00

0.00

Rails 

Django

Hours to Implement 30.00

25.00 Home page Models Project set up Develop Test data HTML Prototype

20.00

15.00

10.00

5.00

0.00

Rails 

Django

Hours to Implement 30.00

25.00 Basic pages Home page Models Project set up Develop Test data HTML Prototype

20.00

15.00

10.00

5.00

0.00

Rails 

Django

Hours to Implement 30.00

25.00 Admin pages Basic pages Home page Models Project set up Develop Test data HTML Prototype

20.00

15.00

10.00

5.00

0.00

Rails 

Django

Hours to Implement 30.00

25.00 Amazon interface Admin pages Basic pages Home page Models Project set up Develop Test data HTML Prototype

20.00

15.00

10.00

5.00

0.00

Rails 

Django

Hours to Implement 30.00

25.00 Data loading code Amazon interface Admin pages Basic pages Home page Models Project set up Develop Test data HTML Prototype

20.00

15.00

10.00

5.00

0.00

Rails 

Django

Hours to Implement 30.00

25.00 Test, tidy Data loading code Amazon interface Admin pages Basic pages Home page Models Project set up Develop Test data HTML Prototype

20.00

15.00

10.00

5.00

0.00

Rails 

Django

Hours to Implement 30.00 26:46

25.00

20.00 16:36

15.00

10.00

5.00

0.00

Rails 

Django

Test, tidy Data loading code Amazon interface Admin pages Basic pages Home page Models Project set up Develop Test data HTML Prototype

Hours to Implement 30.00 26:46

Admin Pages

25.00

20.00 16:36

15.00

10.00

5.00

0.00

Rails 

Django

Test, tidy Data loading code Amazon interface Admin pages Basic pages Home page Models Project set up Develop Test data HTML Prototype

Hours to Implement - without Admin 30.00

25.00

20.00

18:21 15:39

15.00

10.00

5.00

0.00

Rails 

Django

Test, tidy Data loading code Amazon interface Basic pages Home page Models Project set up Develop Test data HTML Prototype

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 600

YAML data loading View/Controller Model

500 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 600

YAML data loading View/Controller Model

500 400 300 200 100 0

Rails

Django

Lines of Code 800 700 600

Authentication YAML data loading View/Controller Model

500 400 300 200 100 0

Rails

Django

Lines of Code 800 700 600

Schema Migration Authentication YAML data loading View/Controller Model

500 400 300 200 100 0

Rails

Django

Lines of Code 800 700 600

HTML Helpers/ Template tags Schema Migration Authentication YAML data loading View/Controller Model

500 400 300 200 100 0

Rails

Django

Lines of Code 800 700 600

Templates HTML Helpers/ Template tags Schema Migration Authentication YAML data loading View/Controller Model

500 400 300 200 100 0

Rails

Django



Hand-coded admin application



Concise



Quicker



Slightly less code

Browser

Browser

Web Server

Web Server

Routes

urls.py

View

Template

Controller

View

Model

Model Rails

Database

Django

Database

Browser

Browser

Web Server

Web Server

Routes

urls.py

View

Template

Controller

View

Model

Model Rails

Database

Django

Database

ActionController::Routing::Routes.draw do |map| map.connect '', :controller => "home"

# Some imports here from hrproj.hr import views urlpatterns = patterns('',

# restful resources map.resources :books do |books| books.resources :readings end

(r'^$', views.index), (r'^readers/$', views.reader_list), (r'^tags/$', views.tag_list), (r'^books/$', views.book_list),

map.resources :readers do |readers| readers.resources :reader_images end

(r'^readers/(?P<username>.*)/$', views.reader_detail), (r'^tags/(?P<slug>.*)/$', views.tag_detail), (r'^books/(?P<slug>.*)/$', views.book_detail),

map.resources :tags end )

/books/hitchhikers-guide-to-the-galaxy

URL Configuration

Browser

Browser

Web Server

Web Server

Routes

urls.py

View

Template

Controller

View

Model

Model Rails

Database

Django

Database

class BooksController < ApplicationController before_filter :find_book def show @reading_paginator, @readings = paginate :readings, :conditions => ["book_id = ?", @book.id] end private def find_book @book = Book.find_by_title(params[:id]) end

def book_detail(request, slug): book = get_object_or_404(Book, slug=slug) queryset = ReadingOccasion.objects \ .filter(book=book) \ .order_by('finished') return standard_view( request, queryset, 'book_detail.html', 'readingoccasion', book=book)

end

Controller / View Function

Browser

Browser

Web Server

Web Server

Routes

urls.py

View

Template

Controller

View

Model

Model Rails

Database

Django

Database

class Reading < ActiveRecord::Base   belongs_to :book   belongs_to :reader end

class ReadingOccasion(models.Model): reader = models.ForeignKey(Reader) book = models.ForeignKey(Book, edit_inline=models.STACKED, num_in_admin=1) finished = models.DateField( core=True) reading_time = models.FloatField( max_digits=5, decimal_places=2, core=True, blank=True) notes = models.TextField( maxlength=2000, blank=True)

class Reading < ActiveRecord::Base   belongs_to :book   belongs_to :reader end

class ReadingOccasion(models.Model): reader = models.ForeignKey(Reader) book = models.ForeignKey(Book, edit_inline=models.STACKED, num_in_admin=1) finished = models.DateField( core=True) reading_time = models.FloatField( 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



In production, you write migration DDL by hand

Django DB evolution

Browser

Browser

Web Server

Web Server

Routes

urls.py

View

Template

Controller

View

Model

Model Rails

Database

Django

Database

books/show.rhtml: <%= render :partial => 'readings/list', :locals => {:key_field => "Reader"} %> readings/_list.rhtml: <%= render :partial => 'readings/reading', :collection => @readings, :locals => {:key_field => key_field} %> readings/_reading.rhtml: <% if key_field == "Book" %> <%= link_to reading.book.title, book_url(reading.book) %> <% else %> <%= link_to reading.reader.fullname, reader_url(reading.reader) %> <% end %> <%= reading.date_read_for_display %> <%= reading.reading_time %> <%= reading.notes %>

book_detail.html: {% for ro in readingoccasion_list %} {{ ro.reader.name }} {{ ro.finished|date:"j M Y" }} {{ ro.reading_time }} {% firstof ro.notes "-" %} {% endfor %}

View / Template

readers/show.rhtml: <%= render :partial => 'readings/list', :locals => { :key_field => "Book" } %> reader_detail.html: {% for ro in readingoccasion_list %} {{ ro.book.title }} {{ ro.finished|date:"j M Y" }} {{ ro.reading_time }} {% firstof ro.notes "-" %} {% endfor %}

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

Django Admin application

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

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



Extracted from Basecamp



“ditched” PHP

Extracted from 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” –



Snakes and Rubies presentation –



http://www.oreillynet.com/pub/a/network/2005/03/10/base

http://video.google.com/videoplay?docid=2939556954580

Django FAQ –

http://www.djangoproject.com/documentation/faq/

Lots of interest in these two frameworks Similar in some ways Different in others How to choose between them?

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

20.00 10:30

15.00

10.00

5.00

0.00

Rails 

Django

Test, tidy Data loading code Amazon interface Admin pages Basic pages Home page Models Project set up Develop Test data HTML Prototype

Related Documents

Comparison
May 2020 20
Comparison
October 2019 34
Comparison
May 2020 30
Comparison
June 2020 20
Comparison
November 2019 33
Comparison
November 2019 36

More Documents from ""