Django for a Rails Developer

by Ashok on November 26, 2009

This is not yet another Django vs Rails blog post. It is a compilation of notes I made working with Django after having worked on Rails for years.

In this post I want to give a brief introduction to Django project layout from a Rails developer point of view, on what is there, what is not there and where to look for things. It should help a rails developer working on django be able to find the necessary files and underatnd the layout of the project files.

Once you have both the frameworks installed on your system you can create the projects using the commands

# creating a rails project
rails rails_project
# creating a Django project
django-admin.py startproject django_project

Lets look at the files and structure created by the respective frameworks

#rails_project
README
Rakefile
app/
    controllers/
        application_controller.rb
    helpers/
        application_helper.rb
    models/
    views/
        layouts/
config/
    boot.rb
    database.yml
    environment.rb
    environments/
        development.rb
        production.rb
        test.rb
    initializers/
        backtrace_silencers.rb
        inflections.rb
        mime_types.rb
        new_rails_defaults.rb
        session_store.rb
    locales/
        en.yml
    routes.rb
db/
    seeds.rb
doc/
    README_FOR_APP
lib/
    tasks/
log/
    development.log
    production.log
    server.log
    test.log
public/
    404.html
    422.html
    500.html
    favicon.ico
    images/
        rails.png
    index.html
    javascripts/
        application.js
        controls.js
        dragdrop.js
        effects.js
        prototype.js
    robots.txt
    stylesheets/
script/
    about
    console
    dbconsole
    destroy
    generate
    performance/
        benchmarker
        profiler
    plugin
    runner
    server
test/
    fixtures/
    functional/
    integration/
    performance/
        browsing_test.rb
    test_helper.rb
    unit/
tmp/
    cache/
    pids/
    sessions/
    sockets/
vendor/
    plugins/

that is huge….

lets look at the django project files

# django_project
__init__.py
manage.py
settings.py
urls.py

far lesser when compared to the rails project.

In fact a rails project comes with everything a web application needs. When I say everything I mean everything….. base application, routing, database configuration, development, test and production environment specific configurations and their respective log files, javascript, test, some standard html files and some helpful scripts for developing.

Why then does a Django project have so less number of files? It has got to do with the Django’s philosophy and the concept of applications. The django project is not complete without the application, so lets create a application inside the project and have a look at the structure

django-admin.py startapp app

# django_project
__init__.py
app/
    __init__.py
    models.py
    tests.py
    views.py
manage.py
settings.py
urls.py

even after including this, the number of files is still less than the rails project.

Lets break it down and relate both the frameworks.

Rails Django
Configuration Files
  • config/database.yml for database settings
  • config/environments/
  • development.rb for development specific settings
  • production.rb for production specific settings
  • test.rb for test specific settings
  • settings.py, one file for everything, database configuration and any other configuaration or settings will be in this file
    URLs config/routes.rb urls.py
    Schema/Models
  • db/schema.rb for the ruby version of db schema
  • app/models/* for the models
  • complete schema is not stored any where
  • Under every application in your project, models.py file will contain the table specific schema stored as django models
  • Management Commands
  • ./script/server, start server
  • ./script/console, ruby console
  • ./script/dbconsole, database console
  • rake db:migrate, run database migrations
  • manage.py is the file for all your tasks
  • ./manage.py runserver, start server
  • ./manage.py shell, python console
  • ./manage.py dbshell, database console
  • ./manage.py syncdb
  • Application Code app/controllers/* will contain the application logic views.py file under each application folder is the place to write to your application logic, file can be named with any name, views.py is the general convention
    Application templates app/views//* is the place for the templates
  • default: looks inside ‘templates’ directory, under the application directory
  • looks in the directory specified by ‘TEMPLATE_DIRS’ in settings.py
  • and lets have a look at the other things in rails_project

    • Logging, unders the logs directory
    • Some default html files for some standard http errors, under the public directory
    • Rails has very good support for testing, for that bunch of files under tests
    • Vendor/Plugin, place for some third party plugins/applications.

    Missing pieces in Django (for a rails developer)

    • Scaffold magic
    • Generate commands
    • Migrations

    and what is Django is providing by default? Sorry no extra files in the project; but you will get an authentication system and Django’s killer feature, admin, just by modifying your ‘INSTALLED_APPS’ in your settings. It is similar to the plugins feature in Rails, Django’s philosophy of resusable apps helps you in getting any particular functionality into your project.

    Following is a list of what I like in Django (and associated apps):

  • Admin (almost everybodys favourite)
  • Generic Views, helps from writing a lot of repetetive code, James Bennett’s blog on generic views
  • Django DB API & QuerySets, (chaining and the filters that are missing in ActiveRecord)
  • Forms and above all, my favorite yet: ModelForm.
  • You can get the migrations feature in Django using South. Being an external app, it a bit of pain in setting it up to work with South. Other than that it is more like rails migrations
  • django-command-extensions
  • Search the Django way
  • Following are the questions that I keep getting,

  • When a project will almost have a application why creating project & app has to be two different steps?
  • Why not create a ‘templates’ directoy and a ‘base.html’ either in project’s directory or in the apps’s directory, because creating the same templates directory and same base.html for every project is not DRY :) ?
  • Why serving static files in development has to be a additional setup, as no developer wants to setup a server for serving static files, I am aware of ‘django.static.serve’ but still that is an additional setup, why not create a sample media directory and a url for the same in urls.py ?
  • let me know via comments, if you have any answers

    program used for listing the files in a directory

    import os
    import sys
    
    try:
        directory = sys.argv[1]
    except IndexError:
        directory = os.path.dirname(os.path.abspath(__file__))
    
    def r_list_dir(directory, indent=0):
        dir_files = sorted([os.path.join(directory, file_name) for file_name in  os.listdir(directory)])
        for item in dir_files:
            if os.path.isdir(item):
                print " " * indent + os.path.split(item)[1] + '/'
                r_list_dir(item, indent+4)
            else:
                print " " * indent + os.path.split(item)[1]
    
    r_list_dir(directory)
    

    Related posts:

    1. Tools of Pro Django developer – aka What powers dinette and almost every app we write.

    3 Comments 46 Tweets 41 Comments

    { 5 trackbacks }

    Django for a Rails Developer — The Usware Blog - Django Web … | Search engine optimization - SEO - Durban - KZN
    November 27, 2009 at 12:51 am
    Random Links #87 | YASDW - yet another software developer weblog
    November 27, 2009 at 11:14 am
    10 Sites Para Você Aprender Django com Aplicações, Livros, Vídeos, Slides e Tutoriais | PedroMenezes.com
    December 11, 2009 at 11:06 am
    Ennuyer.net » Blog Archive » Rails Reading - December 16, 2009
    December 16, 2009 at 8:11 am
    Delicious Bookmarks for January 12th from 17:07 to 17:11 « Lâmôlabs
    January 12, 2010 at 6:11 pm

    { 93 comments… read them below or add one }

    1 shabda November 26, 2009 at 8:49 am

    let me know via comments, if you have any answers

    For the record, I believe all the questions you asked are valid design decisions.

    2 Fidel Ramos November 26, 2009 at 10:33 am

    I’ll answer your questions as I see it, if you want more official answers try django-users.

    When a project will almost have a application why creating project & app has to be two different steps?

    I think it’d be more confusing having two different ways to create a project. And what would happen to INSTALLED_APPS? Also, only the simplest of projects should have only one app. Most will at least reuse other existing apps (like the django-command-extensions you mentioned, or django-registration, django-tagging, etc.)

    Remember the Zen of Python: There should be one– and preferably only one –obvious way to do it.

    Why not create a ‘templates’ directoy and a ‘base.html’ either in project’s directory or in the apps’s directory, because creating the same templates directory and same base.html for every project is not DRY :) ?

    Not everyone uses the “templates” directory. The default setting TEMPLATE_LOADERS also uses the “app_directories” template loader, so applications can have their own “templates” directories.

    I don’t think it would hurt much to have the templates directory created by the startproject command, but it’s not something I miss, I don’t create a project daily you know. It’s the same with the media/static directory.

    Why serving static files in development has to be a additional setup, as no developer wants to setup a server for serving static files, I am aware of ‘django.static.serve’ but still that is an additional setup, why not create a sample media directory and a url for the same in urls.py ?

    In my opinion the best solution would be that the startproject command included the static content serving snippet commented out in the urls.py file, so the developer only needs to create the media dir, uncomment and edit settings.MEDIA_ROOT.

    3 Olivier November 26, 2009 at 10:39 am

    > When a project will almost have a application why creating project & app has to be two different steps? What would the app name be? Its just one more command. Better than ./script/generate {model, controller, view}

    > Why not create a ‘templates’ directoy and a ‘base.html’ either in project’s directory or in the apps’s directory, because creating the same templates directory and same base.html for every project is not DRY ?

    I typically create a ‘templates’ directory in my project’s dir. This makes my apps less reusable. I like how django does not force you to go either way… I’m smart enough to decide when DRY is DRY enough for decisions like these.

    > Why serving static files in development has to be a additional setup, as no developer wants to setup a server for serving static files, I am aware of ‘django.static.serve’ but still that is an additional setup, why not create a sample media directory and a url for the same in urls.py ?

    Good point. It might be a sane default to start with the dev static server.

    4 casseen November 26, 2009 at 11:05 am

    I know it is even used throughout django’s own tutorial, but please do not put applications inside the project folder. It is convenient as django adds the project automatically to the python path, but it will fire back sooner or later. Put your apps somewhere else outside the project folder and add them manually to your python path. The full power of django unfolds when you treat your applications as what they should be: reusable.

    5 Ashok November 26, 2009 at 11:15 am

    @Fidel Ramos, @Olivier

    the views expressed here are from a rails developer point of view, so coming to creating a project & app why not create an application folder with some default name, may be ‘app’ itself.

    Do you ever have comments on the naming of the files urls.py, settings.py, manage.py, models.py, views.py ??, may be not because that is the convention followed ever since you know Django. The same way if you have an application created with the name ‘app’ from beginning, you won’t have any comments on that as well and the INSTALLED_APPS settings can have this app name by default.

    Because of the concept of reusable apps, most of the applications have a ‘templates’ directory inside the application.

    or a default ‘templates’ directory on project level. It is not about forcing anything on the end user, just about some defaults. I mentioned this point because, while going through different tutorials I have to repeat the same steps of creating templates directory, base html almost with the same blocks, so I felt its repetitive and I want this to be default with the framework as every project requires this. Something minimum for getting up & running quickly.

    I feel I used the word DRY wrongly in this context.

    6 Ashok November 26, 2009 at 11:21 am

    @casseen

    agreed..!!

    But the main purpose of framework is not creating reusable apps and it makes more sense for the app to be inside your project directory when you are not developing a reusable app.

    7 Elf Sternberg November 26, 2009 at 8:21 pm

    as no developer wants to setup a server for serving static files…

    Count me as “no developer,” then. I always set up an instance of thttpd as a separate media server for every project, rails or Django, and I often put Nginx (or, soon maybe, Varnish) in front of the whole thing.

    8 panchicore November 26, 2009 at 9:15 pm

    django have the most important things in a web framework (url routing, http framework, i18n i10n engine, orm, is scalable), the other stuff is supplied by enjoying coding, django-pluggables. is about freedom.

    9 Thomas R. Koll November 27, 2009 at 2:43 am

    It sounds strange that so many write about “reusable apps”. I ususally create unique rails apps and anything of wider interest goes into a plugin that I can release separate from the app.

    What does djangos plugin infrastructure look like? Or is one expected to use the python libraries? What does a plugin/library life cycle look like and how fast can new plugins/libraries spread? We now have gemcutter on Ruby which is going to be even faster than it was with rubygems. Does Python have anything similar where everyone can release his libraries?

    10 Clayton December 9, 2009 at 12:19 am

    As a rails developer I’m interested in seeing how other frameworks handle these different concerns (config, templates, generators etc.) I haven’t personally worked with Django but I might check it out a little more seriously now.

    11 uggs sale December 16, 2009 at 8:53 pm

    Nice post here. It does make senses, appreciate for sharing. Thanks!

    12 Ershadul January 12, 2010 at 11:35 pm

    Nice post !

    13 roger February 17, 2010 at 11:28 pm

    Interesting comparison. I’ll admit I really like django because the startup time is quick, and the admin is nice (why doesn’t rails have one by default?) -rp

    21 ulf November 26, 2009 at 10:24 am

    Anyone knows if this exists vice-versa?

    This comment was originally posted on Hacker News

    22 arthurk November 26, 2009 at 10:28 am

    "Why not create a ‘templates’ directoy and a ‘base.html’ either in project’s directory or in the apps’s directory, because creating the same templates directory and same base.html for every project is not DRY?"There’s nothing wrong with that. Even the djangoproject.com website does it like that: http://code.djangoproject.com/browser/djangoproject.com/djan…;

    This comment was originally posted on Hacker News

    23 arthurk November 26, 2009 at 10:28 am

    "Why not create a ‘templates’ directoy and a ‘base.html’ either in project’s directory or in the apps’s directory, because creating the same templates directory and same base.html for every project is not DRY?"There’s nothing wrong with that. Even the djangoproject.com website does it: http://code.djangoproject.com/browser/djangoproject.com/djan…;

    "Why serving static files in development has to be a additional setup, as no developer wants to setup a server for serving static files, I am aware of ‘django.static.serve’ but still that is an additional setup, why not create a sample media directory and a url for the same in urls.py ?"

    Read this: http://www.b-list.org/weblog/2008/jun/23/media/

    This comment was originally posted on Hacker News

    24 arthurk November 26, 2009 at 10:28 am

    "Why not create a ‘templates’ directoy and a ‘base.html’ either in project’s directory or in the apps’s directory, because creating the same templates directory and same base.html for every project is not DRY?"There’s nothing wrong with that. I’ve always done it this way and even the djangoproject.com website does it: http://code.djangoproject.com/browser/djangoproject.com/djan…;

    This comment was originally posted on Hacker News

    25 arthurk November 26, 2009 at 11:28 am

    "Why not create a ‘templates’ directoy and a ‘base.html’ either in project’s directory or in the apps’s directory, because creating the same templates directory and same base.html for every project is not DRY?"There’s nothing wrong with that. Even the djangoproject.com website does it: http://code.djangoproject.com/browser/djangoproject.com/djan…;

    This comment was originally posted on Hacker News

    27 ashok_raavi November 26, 2009 at 10:39 am

    The question is, why not the framework create it automatically ?why one has to create it manually every time a project/app is created ?Atleast a default template directory and a standard base.html on a project level will reduce the repetitive work.

    This comment was originally posted on Hacker News

    28 nailer November 26, 2009 at 10:44 am

    For me the hardest thing about Django was comprehending that the ‘View’ doing most of the work.* urls point to views

    * views do stuff, perhaps involving models

    * the view passes a dict to the template, which is sent as a response to the browser.

    This comment was originally posted on Hacker News

    29 nailer November 26, 2009 at 11:44 am

    For me the hardest thing about Django was comprehending that the ‘View’ doing most of the work.* urls point to views

    * views do stuff, perhaps involving models

    * the view passes a dict to the template, which is sent as a response to the browser.

    Once you get that, it’s not so hard.

    This comment was originally posted on Hacker News

    30 nailer November 26, 2009 at 10:44 am

    For me the hardest thing about Django was comprehending that the ‘View’ doing most of the work.* urls point to views

    * views do stuff. Perhaps hard, manly stuff. Perhaps involving models. The views have hard, beefy beceps.

    * the view passes a dict to the template, which is sent as a response to the browser.

    Once you get that, it’s not so hard.

    This comment was originally posted on Hacker News

    31 nailer November 26, 2009 at 11:44 am

    For me the hardest thing about Django was comprehending that the ‘View’ is doing most of the work.* urls point to views

    * views do stuff. Perhaps hard, manly stuff. Perhaps involving models. Django views have hard, beefy beceps. They’re awfully controlling.

    * the view passes a dict of results to the template, which is sent as a response to the browser.

    Once you get that, it’s not so hard.

    This comment was originally posted on Hacker News

    32 nailer November 26, 2009 at 10:44 am

    For me the hardest thing about Django was comprehending that the ‘View’ doing most of the work.* urls point to views

    * views do stuff. Perhaps hard, manly stuff. Perhaps involving models. Django views have hard, beefy beceps.

    * the view passes a dict of results to the template, which is sent as a response to the browser.

    Once you get that, it’s not so hard.

    This comment was originally posted on Hacker News

    34 ulf November 26, 2009 at 10:45 am

    Actually, if you apply the MVC paradigm, the Django View is a mix of View and Controller. Admittedly a little confusing

    This comment was originally posted on Hacker News

    35 scorpion032 November 26, 2009 at 10:46 am

    A perfect tl;dr.

    This comment was originally posted on Hacker News

    37 scorpion032 November 26, 2009 at 11:59 am

    Hence, it is defined as MTV.

    This comment was originally posted on Hacker News

    38 riffer November 26, 2009 at 11:02 am

    Perfectly stated. I still have the piece of paper from a couple of years ago where I drew this out (I’m both analytical and spatial/visual), and my holistic diagram looks just like what you wrote.At the risk of being negative, I think the real issue is that the extensive documentation is geared more towards designers than hackers.

    This comment was originally posted on Hacker News

    40 neelesh November 26, 2009 at 11:30 am

    "Why serving static files in development has to be a additional setup, as no developer wants to setup a server for serving static files, I am aware of ‘django.static.serve’ but still that is an additional setup, why not create a sample media directory and a url for the same in urls.py" – Because typical deployments don’t use django for serving static files?

    This comment was originally posted on Hacker News

    41 shabda November 26, 2009 at 12:39 pm

    however typical developments do, and this question is about typical development setup

    This comment was originally posted on Hacker News

    43 uggedal November 26, 2009 at 1:04 pm

    No one goes from Django to Rails…

    This comment was originally posted on Hacker News

    45 icey November 26, 2009 at 1:13 pm

    Hmmm…. I do Django stuff but I’m working on my first Rails project right now. A Django -> Rails guide would be useful to me.

    This comment was originally posted on Hacker News

    46 FraaJad November 26, 2009 at 1:24 pm

    I am far far away from being considered a designer and I consider the Django documentation to be excellent for programmers. Just because it also caters to designers, the documentation is not necessarily watered down.

    This comment was originally posted on Hacker News

    47 neelesh November 26, 2009 at 1:38 pm

    Agree. What we probably need is a nice way to switch between deployment/development setups, possibly by splitting settings.py like rails

    This comment was originally posted on Hacker News

    49 suvike November 26, 2009 at 2:04 pm

    the usual trick is to use a local_settings.py.put all of your environment-specific variables in there, and put ‘from local_settings.py import *’ at the end of your settings.py

    This comment was originally posted on Hacker News

    Leave a Comment

    Additional comments powered by BackType

    Previous post:

    Next post: