hank / life

Good code.

This URL has Read+Write access

life / oscon / 2008 / tutorials / Django.rdoc
100644 96 lines (73 sloc) 2.861 kb

OSCON 2008, Tutorial 2: Introduction to Django

Slides: toys.jacobian.org/presentations/2008/oscon/tutorial/

  • Django isn’t really MVC, just kinda
  • SQL is hard
  • No version control for SQL
  • You can use Rails Migrations with Django
  • A manager contains the logic to connect Python to the database.
  • You don’t have to do has_one if you do belongs_to

Finding things

  license = Topic.objects.get(name="License")
  license.categories.filter(value__startswith="OSI")

  bsd = license.categories.get(value__contains="BSD")
  p = Package.categories.get(name="Shop");
  p.categories = [bsd]

Show all Spanish-language packages with a BSD license

  packages = Package.objects.filter(
    categories__topic__name = "Natural language",
    categories__value__contains = "Spanish"
  )

It figures out the correct JOIN. So awesome.

Another way

  packages = Package.objects.filter(
    categories__topic__name = "Natural language",
  )
  packages.filter(
    categories__value__contains = "Spanish"
  )

This actually doesn’t do 2 SQL queries. It returns a lazy object (query set), which doesn’t execute until you access it. It build up queries automatically.

Adding an admin interface

  • The admin interface is really pretty and cool
  • has a really nice permissions interface for CRUD for users

URLs

  • Some URLs really suck.
  • Django has pretty URLs
  • Redirects to */ automatically
  • matching happens in order
  • include() makes it nice when you want to pass it off to another urls.py

Views

  • must take a request as the first param
  • Must return an HttpResponse object or a subclass

Making some nice views

  def package_list(request):
    return HttpResponse("This is the package list!")

  def package_list(request):
    r = "<ul>"
    ps = Package.objects.order_by("name")
    for p in ps:
      r += "<li%s: %s</li>" % \
        (p.name, p.description)
    r += "</ul>"
    return HttpResponse(r);

Well, that sucks because we’re embedding HTML in our Python!

MTV (Model View Template) = Views pull the data, pass them to the template

  def package_list(request):
    ps = Package.objects.order_by("name")
    t = template.loader.get_template("packages/index.html")
    c = Context({"package_list": ps})
    return HttpResponse(t.render(c))

"You’re welcome to call a View a Controller"

The purpose of a controller is to connect the business logic to the frontend. The views in Django are only to send things into templates (more like 4 layers)

Templates

  • */end* block syntax (for/endfor, if/endif, etc)
  • Similar to liquid, apparently taken from smarty and cheetah?

The magic dot

  p["name"]
  p.name
  p.name()
  • extends must be the first thing in your template
  • more {% block %}s are better

direct to template is hawt:

  (r'^$', direct_to_template, {'template':'homepage.html'}),