Jumpstart


                  The Web Framework
            for Perfectionists with Deadlines


                                         CPOSC
Rob Yates                                October, 2009
Topics
Topics
• What is Django
Topics
• What is Django
• History of Django
Topics
• What is Django
• History of Django
• Whirlwind Tour
Topics
• What is Django
• History of Django
• Whirlwind Tour
• How to Get Started - Admin Demo
Topics
• What is Django
• History of Django
• Whirlwind Tour
• How to Get Started - Admin Demo
• Killer Features
Topics
• What is Django
• History of Django
• Whirlwind Tour
• How to Get Started - Admin Demo
• Killer Features
• Application Re-use and Pinax
Topics
• What is Django
• History of Django
• Whirlwind Tour
• How to Get Started - Admin Demo
• Killer Features
• Application Re-use and Pinax
• Framework Death-match
What is Django?
What is Django?
•   Not a Gypsy Jazz Guitarist
What is Django?
•   Not a Gypsy Jazz Guitarist

•   Web Application
    Development Framework
    written in and for Python
What is Django?
•   Not a Gypsy Jazz Guitarist

•   Web Application
    Development Framework
    written in and for Python

•   Not a CMS System
What is Django?
•   Not a Gypsy Jazz Guitarist

•   Web Application
    Development Framework
    written in and for Python

•   Not a CMS System

•   Sometimes called Python’s
    Ruby on Rails (RoR)
It all started
                          HERE




Photo by Jeff Croft
Simon Willison




Adrian Holovaty
PyCon 2005
Major topic: Why is web development
         in Python so hard?
Jump to today:
Guiding Principles
Jump to today:
    Guiding Principles
• Loose Coupling and tight cohesion
Jump to today:
    Guiding Principles
• Loose Coupling and tight cohesion
• Less code
Jump to today:
    Guiding Principles
• Loose Coupling and tight cohesion
• Less code
• Quick development
Jump to today:
    Guiding Principles
• Loose Coupling and tight cohesion
• Less code
• Quick development
• DRY
Jump to today:
    Guiding Principles
• Loose Coupling and tight cohesion
• Less code
• Quick development
• DRY
• Explicit is better than implicit
Jump to today:
    Guiding Principles
• Loose Coupling and tight cohesion
• Less code
• Quick development
• DRY
• Explicit is better than implicit
• Consistency
For Free!!!
           • Very Useful Admin CRUD
           • Templating - lots of useful rendering bits
           • Form Handling
           • i18n - full Unicode support
           • Sessions / User Auth / Role-based Perms
           • Object-Relational Mapping
Beer photo by Lori Spindler
Model View Controller
Model View Controller

            Model
            View
            Template
Models
Templates




            App
 Views

 Models
Templates
            App

 Views
                  Site




 Models
Templates
            App




 Views

    Settings
     URLs
                         Django App Structure




   Templates
Architecture
                       RDBMS

   Storage             ORM        Fixtures

                       Model

Signals        Forms              Template

URL Resolver           View    Template Loader


 Middleware                      Middleware

   Request                        Response
Deep Dive: Models
from tagging.fields import TagField

class Post(models.Model):
  author = models.ForeignKey(Author)
  title = models.CharField(max_length=200)
  slug = models.SlugField(max_length=200, unique_for_month='pub_date')
  body = models.TextField()
  TYPE_CHOICES = (
    ('rant', 'Rant'),
    ('tirade', 'Tirade'),
  )
  type = models.CharField(choices=TYPE_CHOICES, max_length=50)
  pub_date = models.DateTimeField(auto_now_add=True)
  is_active = models.BooleanField(default=True)
  tags = TagField(blank=True, null=True)

  class Meta:
    unique_together = ('title', 'type')
    ordering = ['-pub_date']
Architecture
                       RDBMS

   Storage             ORM        Fixtures

                       Model

Signals        Forms              Template

URL Resolver           View    Template Loader


 Middleware                      Middleware

   Request                        Response
Deep Dive: DB API
post = Post(title=‘Foo’, body=‘Bar’)
post.type = ‘rant’
post.save()
Deep Dive: DB API
post = Post(title=‘Foo’, body=‘Bar’)
post.type = ‘rant’
post.save()

posts = Post.objects.all()

posts = Post.objects.all()[:5]

posts = Post.objects.filter(post_type=‘rant’)

posts = Post.objects.filter(author__name=‘Rob’)

posts = Post.objects.filter(author__name=‘Rob’).
    filter(title__contains=‘django’).order_by(‘type’)

post = Post.objects.get(id=24)
Architecture
                       RDBMS

   Storage             ORM        Fixtures

                       Model

Signals        Forms              Template

URL Resolver           View    Template Loader


 Middleware                      Middleware

   Request                        Response
Deep Dive: Forms
# Basic Form
class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField()
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)
Deep Dive: Forms
# Basic Form
class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField()
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)



# Form based on a model
class PostForm(forms.ModelForm):
    class Meta:
        model = Post
Deep Dive: Views
def posts_by_type(request, type):
    posts = Post.objects.filter(type=type)

    return render_to_response(
            ‘postsbytype.html’, {‘posts’: posts})
Deep Dive: Views
def posts_by_type(request, type):
    posts = Post.objects.filter(type=type)

    return render_to_response(
            ‘postsbytype.html’, {‘posts’: posts})


def new_post(request):
    if request.method == ‘POST’:
        form = PostForm(request.POST)
        if form.is_valid():
            form.save()
    else:
        form = PostForm()
    return render_to_response(
            ‘mytemplate.html’, {‘form’: form})
Architecture
                       RDBMS

   Storage             ORM        Fixtures

                       Model

Signals        Forms              Template

URL Resolver           View    Template Loader


 Middleware                      Middleware

   Request                        Response
Deep Dive: URLs
urlpatters = patterns(‘’,
    (’^my/favorite/color/$’, ‘blog.views.my_fav_color’),
    (‘^post/new/$’, ‘blog.views.new_post’),



    (‘^posts/(d{4})/$’, ‘blog.views.year_archive’),
    (‘^posts/(d{4})/(d{2})/$’, ‘blog.views.month_archive’),



    (‘^posts/(?P<slug>[a-z-]*)/$’, ‘blog.views.show_post’),



    (‘^events/$’, include(events.urls),
)
Architecture
                       RDBMS

   Storage             ORM        Fixtures

                       Model

Signals        Forms              Template

URL Resolver           View    Template Loader


 Middleware                      Middleware

   Request                        Response
Architecture
                       RDBMS

   Storage             ORM        Fixtures

                       Model

Signals        Forms              Template

URL Resolver           View    Template Loader


 Middleware                      Middleware

   Request                        Response
Deep Dive: Templates
<html><body>
   {% if posts %}
      {% for post in posts %}
         {{ post.author }}: {{ post.title }}
      {% endfor %}
   {% endif %}
Deep Dive: Templates
<html><body>
   {% if posts %}
      {% for post in posts %}
         {{ post.author }}: {{ post.title }}
      {% endfor %}
   {% endif %}


<form method=”post”>
   <table>
      {{ form }}
   </table>
</form>
Deep Dive: Templates
<html><body>
   {% if posts %}
      {% for post in posts %}
         {{ post.author }}: {{ post.title }}
      {% endfor %}
   {% endif %}


<form method=”post”>
   <ul>
      {{ form.as_ul }}
   </ul>
</form>
Architecture
                       RDBMS

   Storage             ORM        Fixtures

                       Model

Signals        Forms              Template

URL Resolver           View    Template Loader


 Middleware                      Middleware

   Request                        Response
Getting Started
• Pure Python - no compiled code
• No dependencies (with the exception of
  the database adapter of your choice
• Three-step install
 • D/L and extract tar
 • Run setup.py
 • Add django-admin.py to path (optional)
Initialize Your Project
$ django-admin.py startproject mysite
$ cd mysite
$ python manage.py startapp myapp
$ edit settings.py and set DB Info
$ python manage.py runserver


        http://localhost:8000
Killer Features
•   Legacy DB            •   Generic Views

•   Test Framework       •   Template Inheritance

•   Multi-DB             •   Tempalte Filters

•   Geodjango            •   Humanize

•   Aggregation          •   Runs on Jython /
                             IronPython
•   JSON Serializer

•   Stable API Promise   •   Google AppEngine!

•   Fantastic Docs
Roll Your Own
• Model Managers: Custom database API for views
• Custom Template Tags: Easier to implement
  functionality without mixing logic/presentation
Roll Your Own
• Model Managers: Custom database API for views
• Custom Template Tags: Easier to implement
  functionality without mixing logic/presentation


  • ORM Layer       • Model Fields
  • Template Engine • Form Fields
  • Template Loader • URL Resolver
Re-usable Apps
         and Pinax
• Following best practices when creating
  your app allows others to plug in and use it
• Search Google Code for *django* projects
  returns 1,987 results - many are apps
• James Tauber created Django Hotclub to
  establish standards for app development
  and integration
• Hotclub later become Pinax
Framework Death-match




Photo by Bruce Turner
Death-match: RoR

•   URL Handling

    •   RoR: RESTful with HTTP verbs

    •   Django: RegEx-based URL patterns

•   JavaScript / AJAX

    •   RoR: XHR helpers with RJS, prototype, scriptaculous

    •   Django: JS framework agnostic / no helpers besides
        serialization
Death-match: RoR

•   Unicode

    •   Ruby traditionally has had issues - string is byte sequence

    •   Python is fully Unicode since v1.6 (circa 2000)

•   i18n

    •   RoR: Translations are copied - no fallback?

    •   Django: Translations use GNU gettext-style localization -
        falls back to default language
Death-match: RoR

•   Plugins

    •   RoR: Rich plugin API and structure

    •   Django: Re-usable applications

•   Automation / Build

    •   RoR: rake is a rich scripting language for automated tasks

    •   Django: manage.py can do some basic tricks - CLI
Death-match: RoR
•   Jobs: Rails jobs out-number Django jobs 6:1

•   Hype: Rails has done a fantastic job with marketing
Death-match: RoR
•   Jobs: Rails jobs out-number Django jobs 6:1

•   Hype: Rails has done a fantastic job with marketing
Recap
Recap
• Django is easy
Recap
• Django is easy
• Django is fun
Recap
• Django is easy
• Django is fun
• Django scales
Recap
• Django is easy
• Django is fun
• Django scales
• Django is maintainable
Recap
• Django is easy
• Django is fun
• Django scales
• Django is maintainable
• Django saves small kittens
Recap
• Django is easy
• Django is fun
• Django scales
• Django is maintainable
• Django saves small kittens
• It rocks - USE IT!
Resources
• http://djangoproject.com
 • Check out the tutorial!
• http://docs.djangoproject.com
• http://djangodose.com
• http://www.b-list.org/
• http://pinaxproject.com
• http://code.google.com/hosting/search?
  q=label%3aDjango
Thanks!
 rob@robyates.org

Twitter: @Rob_Yates
 http://robyates.org