0
Web Development with Python and Django  Mike Crute • Mike Pirnat • David Stanek
Today• Iteratively build a full-featured site• Background for each feature• Implement a feature• Review our example soluti...
Useful Links• http://docs.python.org• https://docs.djangoproject.com• https://github.com/finiteloopsoware/  django-precomp...
Let’s Have a Show of Hands...
Django
Django?
Django
Django• A high-level Python web framework• Encourages rapid development and clean,  pragmatic design• “For perfectionists ...
Perhaps You’ve Heard Of...• Disqus        • Pinterest• Instagram     • PolitiFact.com• Mozilla       • Rdio• OpenStack
Django• ORM                      • Cache infrastructure• Automatic admin          • Internationalization  interface       ...
Python(the Short-Short Version)
Python is... • Dynamic               • Exceptional • Interpreted           • Comfortable • Duck-Typed            • Readabl...
Interactive Shell$ python>>> print "Hello, world!"Hello, world!>>>$ python3>>> print("Hello, world!")Hello, world!>>>
Comments# Best. Code. Evar.
Booleans and NullTrueFalseNone
StringsHello, world!"Hello, world!""""Hello,world!"""u"Hëllö, wörld!"
String Operations"foo" + "bar""foo"[0]"foo"[:1]"foo".upper()"{0}: {1}".format("foo", "bar")"{foo}: {bar}".format(foo=42, b...
Numeric Types4242.042L
Lists, Tuples, and Sets[a, b, c](Rush, 2112, 5.0)set([a, b, c])
Sequence Operations[...][0][...][-1][...][:1]    # same as [...][0:1][...].append(4)[...].extend([4, 5, 6])[...].pop()len(...
Dictionaries{key1: value1, key2: value2}
Dictionary Operations{...}[key1]{...}.get(key2, default){...}.keys(){...}.values(){...}.items()len({...})
Assignment & Comparisonfoo = barfoo == bazfoo != bazfoo is Nonefoo is not None
Flow Controlif expression:    ...elif expression:    ...else:    ...
Flow Controlfor item in sequence:    if expression:        continue    if expression:        break
Flow Controlwhile expression:    if expression:        continue    if expression:        break
Functionsdef foo():    return 42def foo(bar):    return bardef foo(bar, baz=quux):    return (bar, baz)def foo(*args, **kw...
Decorators@bardef foo():     return 42@baz(xyzzy)def quux():    return 42
Classesclass Foo(object):    def __init__(self, bar):        self.bar = bar
Docstrings"Modules can have docstrings."class Foo(object):    "Classes can have docstrings too."    def __init__(self, bar...
Exceptionstry:    raise Exception("OH NOES!")except:    log_error()    raiseelse:    do_some_more()finally:    clean_up()
Namespacesimport loggingfrom datetime import timedeltafrom decimal import Decimal as D
Introspection>>> dir(Foo)[__class__, __delattr__, __dict__, __doc__,__format__, __getattribute__, __hash__,__init__, __mod...
Introspection>>> help(Foo)Help on class Foo in module __main__:class Foo(__builtin__.object) | Classes can have docstrings...
And more...• Generators              • Properties• Generator Expressions   • Context Managers• List Comprehensions     • C...
Style: PEP-8• No tabs                   • Line breaks around                              78-79 chars• Four-space indents ...
Setup
Environment Setup• Mac or Linux? You’ve already got Python!• You’ll also need Git if you don’t have it;  download it from ...
Windows Setup• Portable Python and Portable Git• Won’t modify your system at all• Can be easily uninstalled• If you want t...
Portable Python 2.7• Download http://bit.ly/13eyQGn  http://p.osuosl.org/pub/portablepython/v2.7/PortablePython_2.7.3.1.e...
Portable Git• Download http://bit.ly/X4dGps  http://msysgit.googlecode.com/files/Git-1.8.0-preview20121022.exe• Create a ne...
Fixing the Path• Download:  https://gist.github.com/4399659• Save it as a file named run-cmd.bat• Run it• Download wont wor...
Installing Packages• easy_install: easy_install package• pip: pip install package
Installing Packages• Installed packages go into a site-packages  directory in your Python lib• That’s the “system Python” ...
Virtual Environments• virtualenv• Creates an isolated Python environment  with its own site-packages• Install whatever you...
Python 2 or 3?• The future of Python is Python 3• Django 1.5 has experimental Python 3  support• Python 2.7 is still recom...
Activate the Virtual Environment# Mac/Linux/etc...$ virtualenv django-precompiler$ cd django-precompiler$ source bin/activ...
The Django Stack
Request           DjangoResponse
Request          Framework          Middleware           Django          URLs                               Response      ...
The Project...
CODE SMASH!• Code Smash is a fictional soware  development conference for people who  need to punch out awesome code• It n...
Starting a Project# Normally...$ git init src# Today...$ git clone https://github.com/finiteloopsoftware/django-precompile...
Defining Requirements • requirements.txt • A basic example:MyAppFramework==0.9.4Library>=0.2http://someserver.org/packages/...
Requirements• Create a requirements.txt• Require Django version 1.5; use:  https://www.djangoproject.com/download/1.5c1/ta...
Installing Requirements$ pip install -r requirements.txt
Starting a Project# Mac/Linux/etc.$ django-admin.py startproject codesmash ./$ python manage.py runserver# Windows> python...
New Project Contentssrc/    codesmash/        __init__.py        settings.py        urls.py        wsgi.py    manage.py
A Static Home Page
Templates• Make a templates directory under src:  $ mkdir templates• Update settings to tell Django where to find  the temp...
URLs• Map URLs in requests to code that can be  executed• Regular expressions!• Subsections of your site can have their ow...
URLsfrom django.conf.urls import patterns, include, urlurlpatterns = patterns(,    url(r^$, codesmash.views.home, name=hom...
Views• Code that handles requests• Other frameworks oen call these  “controllers”• Basically a function that:  • gets a r...
Viewsfrom django.http import HttpResponsedef my_view(request):    return HttpResponse("Hello, world!")                    ...
Viewsfrom django.http import HttpResponsefrom django.template import Context, loaderdef my_view(request):    template = lo...
Viewsfrom django.shortcuts import renderdef my_view(request):    return render(request, template.html, {...})             ...
Exercise 1• Create a template for the homepage• Create a view that will respond with the  rendered template• Connect the /...
Let’s see the code!git reset --hard ex01
Contact Form
Apps• Django believes strongly in separating  chunks of a site into apps that can be reused• Ecosystem of reusable apps av...
New App Contentssrc/    codesmash/   myapp/       __init__.py       models.py       tests.py <-- you should write them!   ...
App URLsfrom django.conf.urls import patterns, include, urlurlpatterns = patterns(myapp.views,    url(r^$, my_view, name=m...
Connecting App URLs# Use include to connect a regex to an apps urls.py# Use namespace to keep app URL names nicely isolate...
Form Validation• Why?• Classes for each kind of input field• Form class to gather input fields• View method uses the form cl...
A Very Simple Formfrom django import formsclass MyForm(forms.Form):    name = forms.CharField(max_length=30)    email = fo...
Using a Form in a Viewfrom myapp.forms import MyFormdef my_view(request):    form = MyForm(request.POST or None)    if req...
Django Template Language• Call a function or do logic:  {% ... %}• Variable substitution:  {{ bar }}• Filters:            ...
Forms in Templates<html>...    <body>       <form action="{% url myapp:my_form %}"        method="post">           {% csrf...
Sending Mail• Add an EMAIL_BACKEND in settings.py EMAIL_BACKEND =      django.core.mail.backends.console.EmailBackend• Imp...
Exercise 2• Create a contact app• Create a contact form with subject,  message, and sender’s email address• Create view to...
Let’s see the code!git reset --hard ex02
Redirecting on Success• Make the POST action redirect with a GET  on successful processing• Avoid “resubmit form” issues w...
Redirectingfrom django.shortcuts import redirectdef my_view(request):    ...    return redirect(namespace:name)           ...
Exercise 3• Make a separate contact form URL and  template for displaying a success message• Update the POST handler to re...
Let’s see the code!git reset --hard ex03
A Consistent Appearance
Template Inheritance• Define a base template for the site• Other templates extend the base template• Blocks allow child tem...
base.html<!DOCTYPE html><html>    <head>        <meta name="..." content="...">        <title>{% block title %}My Site{% e...
helloworld.html{% extends "base.html" %}{% block title %}Hello, World{% endblock %}{% block content %}    <h1>Hey! Great!<...
Exercise 4• Refactor those templates!• Make a base.html with appropriate blocks• Make other templates extend it and fill in...
Let’s see the code!git reset --hard ex04
User Registration
No Need to Reinvent• Django comes with a robust user  framework: django.contrib.auth• Registration• Login/Logout• Password...
Database Settingsimport osPROJECT_ROOT = os.path.abspath(        os.path.join(os.path.dirname(__file__), ".."))DATABASES =...
Create the Database$ python manage.py syncdb                             Framework                             Middleware ...
Extend the UserCreationFormfrom django.contrib.auth.forms import UserCreationFormclass RegistrationForm(UserCreationForm):...
Register the Userform = RegistrationForm(request.POST)if form.is_valid():    form.save()                                  ...
Login Aer Registrationfrom django.contrib.auth import authenticate, loginuser = authenticate(    username=form.cleaned_da...
The User Object• Always have one in every request• Always available to templates• Can be anonymous or populated depending ...
Exercise 5• Start a new app called            • Profile page should just  “accounts”                          display usern...
Let’s see the code!git reset --hard ex05
User Login & Logout
More Reusable Goodness• django.contrib.auth provides URLs and  views for login and logout• Will want to provide our own te...
URLsurlpatterns = patterns(,    ...    (rauth/, include(django.contrib.auth.urls,            namespace=auth)),    ...)    ...
Templates to Override• templates/registration/login.html• templates/registration/logged_out.html                          ...
Login/Logout Links{% url auth:login %}{% url auth:logout %}                           Framework                           ...
Differentiate Logged In/Out{% if user.is_authenticated %}    ...{% else %}    ...{% endif %}                               ...
Exercise 6• Enable auth URLs           • Show username in                               header when user is• Add login and...
Let’s see the code!git reset --hard ex06
Django Admin
Django Admin• Free CRUD!• Navigate database data by model• Make changes• Highly customizable                              ...
Enabling the Admin App• Uncomment admin lines from  INSTALLED_APPS in settings.py• Uncomment admin lines from the project’...
Demo Time!git reset --hard ex07
CMS Pages
django.contrib.flatpages• Store simple “flat” HTML pages in the  database• Has a URL, title, and content• Useful for one-off ...
settings.py• Add to INSTALLED_APPS:  django.contrib.flatpages• Add to MIDDLEWARE_CLASSES:  django.contrib.flatpages.middle...
urls.py•Change root URL to use flatpage:url(r^$, django.contrib.flatpages.views.flatpage,        {url: / }, name=home)     ...
Make a Flatpage Template• Put it in templates/flatpages/default.html• In the title block, add:  {{ flatpage.title }}• In th...
Let’s see the code!git reset --hard ex08
Meanwhile, in the admin app...
Conference Talks:An App with a Custom Data Model
Models• Model classes are the nouns of the system• Used to create database tables• Integrated with the ORM to interact wit...
Modelsfrom django.db import modelsclass Thingy(models.Model):    name = models.CharField(max_length=255)    awesome = mode...
Exercise 9• Create a “talks” app to manage talks• Create a Talk model; it should have:  • title - up to 255 characters  • ...
Let’s see the code!git reset --hard ex09
Wiring the Model for Admin Access • Each app manages its own admin wiring • Goes into an admin.py within the app          ...
admin.pyfrom django.contrib import adminfrom myapp.models import Thingyadmin.site.register(Thingy)                        ...
Exercise 10• Create an admin.py for the talks app• Register the Talk model• Start up the admin app and verify that Talks  ...
Let’s see the code!git reset --hard ex10
Pluralize All the Thingys!class Thingy(model.models):    ...    class Meta:        verbose_name_plural = "Thingies"       ...
Relations• Foreign key (one-to-many)• Many-to-many                               Framework                               M...
Foreign Key Relationsclass Thingy(models.Model):    ...class Gadget(models.Model):    ...class Gizmo(models.Model):    thi...
Many-to-Many Relationsclass Thingy(models.Model):    ...class Gizmo(models.Model):    thingies = models.ManyToManyField(Th...
Saving a Model Objectthingy = Thingy()thingy.size = bigthingy.save()gadget = Gadget(thingy=thingy)gadget.save()gizmo = Giz...
Exercise 11• Create new model classes   • All should have a name, up  for foreign keys:            to 255 characters  • Ca...
Let’s see the code!git reset --hard ex11
Meanwhile, in the admin app...
Changing Existing Models• Adding/removing/changing fields in a  model requires a schema migration• Django doesn’t support i...
Cheesy Precompiler Way $ ./manage.py dbshell > DROP TABLE talks; $ ./manage.py syncdb                          Framework  ...
Querying the Modelall_thingies = Thingy.objects.all()single_thingy = Thingy.objects.get(id=1)big_thingies = Thingy.objects...
Relations in Templates• When a model object retrieved from the  ORM has relations, you get a relation  manager and not an ...
Relations in Templates{% for gizmo in gizmos %}    {% for thingy in gizmo.thingies.all %}        ...    {% endfor %}{% end...
Exercise 12• Create a view and template to display a list  of all talks, ordered by title• Be sure to display all of the t...
Let’s see the code!git reset --hard ex12
Optimizing Queries• What we just did will make lots of extra  database queries (because of the loops)• Go read up on:  • s...
Model Managers• A place to encapsulate data queries• Extend to provide extra queries with  developer-friendly interfaces  ...
Model Managersclass ThingyManager(models.Manager):    def big_ones(self):        return self.get_query_set().filter(size=b...
Using a Model Managerbig_thingies = Thingy.objects.big_ones()green_thingies = Thingy.objects.of_color(green)              ...
Exercise 13• Move the queries from the previous exercise  into a TalkManager• Change the queries to only get talks that  h...
Let’s see the code!git reset --hard ex13
Generic Views• Many views fall into the same patterns• Django provides generic view classes for  things like showing a lis...
Generic List Viewsfrom django.views.generic import ListViewclass ThingyListView(ListView):   queryset = Thingy.objects.all...
Generic List View URLsfrom django.conf.urls import patterns, include, urlfrom myapp.views import ThingyListViewurlpatterns...
Generic List View Templates• Generic List Views are automatically wired  to templates• Naming convention: lowercase model ...
Exercise 14• Replace the view that lists talks with a  generic list view• Redo the URL mapping to use your new  generic li...
Let’s see the code!git reset --hard ex14
Can You Guess What’s Next?• Need to create new talks• We could do it the hard way...  • Make a Form  • Make a View  • Read...
Model Formsfrom django import formsfrom myapp.models import Thingyclass ThingyForm(forms.ModelForm):    class Meta:       ...
Generic Create Viewsfrom django.views.generic.edit import CreateViewfrom myapp.forms import ThingyFormclass ThingyCreation...
Generic Create View Templates• Generic Create Views are automatically  wired to templates• Naming convention: lowercase mo...
Exercise 15• Make a Generic Create      • Be sure to connect a  View and Model Form to       “create” URL to the new  subm...
Let’s see the code!git reset --hard ex15
Generic Edit Viewsfrom django.shortcuts import resolve_urlfrom django.view.generic.edit import UpdateViewfrom myapp.forms ...
Generic Edit View URLsfrom django.conf.urls import patterns, include, urlfrom myapp.views import ThingyUpdateViewurlpatter...
Exercise 16• Create a Generic Edit View for talks• Use the Model Form from the previous  exercise• Be sure to wire it to a...
Let’s see the code!git reset --hard ex16
Security in Views• Can you spot a security problem in the  previous exercise?• Anyone can edit any talk!• Generic views ca...
Restricting Object Access# In models.py...class ThingyManager(models.Manager):    def for_user(self, user):        return ...
Exercise 17• Lock down the update view from the  previous exercise so that a talk may only be  edited by its speakers     ...
Let’s see the code!git reset --hard ex17
Read-Only Data in Generic Edit Views • Model Form automatically builds form   elements for everything in the model • Model...
Read-Only Data in Generic Edit Views<form ...>    {% csrf_token %}    {{ form.as_p }}    <p><input type="text" id="flavor"...
Exercise 18• Change the talk form from the previous  exercises• Show time slot, location, and approval  status without all...
Let’s see the code!git reset --hard ex18
Requiring Loginfrom django.contrib.auth.decorators import         login_required@login_requireddef my_login_only_view(requ...
Exercise 19• Require login on the user profile page                                           Framework                    ...
Let’s see the code!git reset --hard ex19
Custom Template Filters• Django comes with many filters• You can add your own• Function that accepts a value and returns a ...
Defining a Custom Filter# In myapp/templatetags/myfilters.py...from django import templatefrom django.utils.html import for...
Using a Custom Filter{% load myfilters %}{% block content %}   <p>{{ foo|my_filter }}</p>   <p>{{ bar }}</p>{% endblock %}...
Exercise 20• Create a custom filter function  “boolean_icon” that will show one image if  a value is True and another if it...
Let’s see the code!git reset --hard ex20
Bonus Exercises• Show talks by time slot and/or location• Blog; include RSS feed• Sponsorship; include sponsor image uploa...
A Little Bit About Deployment
Django
Varnish           NginxStatic Files    Gunicorn                   Django                   Django                    Django
Where to Deploy• Gondor.io• Heroku• Webfaction• Google App Engine  (if that’s what you’re into)• Your favorite VPS (Racksp...
Questions?
Links• http://python.org• https://djangoproject.com• https://github.com/finiteloopsoware/  django-precompiler
Credits• Image from Django Unchained by Sony  Pictures  http://www.nydailynews.com/entertainment/tv-movies/django-star-fox...
Contact Information Mike Crute                 David Stanek   Finite Loop Soware        American Greetings   http://mike....
Thanks for coming & happy hacking!
Upcoming SlideShare
Loading in...5
×

Web Development with Python and Django

26,488

Published on

Slides from our CodeMash 2013 Precompiler session, "Web Development with Python and Django", including a breezy introduction to the Python programming language and the Django web framework. The example code repository is available at https://github.com/finiteloopsoftware/django-precompiler/

Published in: Technology
3 Comments
83 Likes
Statistics
Notes
  • Try running a slide karaoke with it at your next local user group meeting - I am sure the group will come up with something just as instructive as the original talk (which, from what I know of the authors, was most likely great)
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • @nfdotnet Unfortunately this was was not recorded; very few CodeMash talks are recorded during the conference, and they haven't recorded the tutorials at all.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Is there audio or video to go along with this awesome slide deck? I could follow most of the slides without much else but I would really like to hear the actual presentation. if it is available.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
26,488
On Slideshare
0
From Embeds
0
Number of Embeds
28
Actions
Shares
0
Downloads
775
Comments
3
Likes
83
Embeds 0
No embeds

No notes for slide

Transcript of "Web Development with Python and Django"

  1. 1. Web Development with Python and Django Mike Crute • Mike Pirnat • David Stanek
  2. 2. Today• Iteratively build a full-featured site• Background for each feature• Implement a feature• Review our example solution • Keep yours? git show tag • Follow directly? git reset --hard tag
  3. 3. Useful Links• http://docs.python.org• https://docs.djangoproject.com• https://github.com/finiteloopsoware/ django-precompiler/wiki
  4. 4. Let’s Have a Show of Hands...
  5. 5. Django
  6. 6. Django?
  7. 7. Django
  8. 8. Django• A high-level Python web framework• Encourages rapid development and clean, pragmatic design• “For perfectionists with deadlines”• Focus on automation and DRY• Widely supported, many deployment options
  9. 9. Perhaps You’ve Heard Of...• Disqus • Pinterest• Instagram • PolitiFact.com• Mozilla • Rdio• OpenStack
  10. 10. Django• ORM • Cache infrastructure• Automatic admin • Internationalization interface • Command-line job• Regex-based URL design framework• Templating system
  11. 11. Python(the Short-Short Version)
  12. 12. Python is... • Dynamic • Exceptional • Interpreted • Comfortable • Duck-Typed • Readable • Object-Oriented • Opinionated • Functional • Batteries Included • Strongly-Namespaced • Community
  13. 13. Interactive Shell$ python>>> print "Hello, world!"Hello, world!>>>$ python3>>> print("Hello, world!")Hello, world!>>>
  14. 14. Comments# Best. Code. Evar.
  15. 15. Booleans and NullTrueFalseNone
  16. 16. StringsHello, world!"Hello, world!""""Hello,world!"""u"Hëllö, wörld!"
  17. 17. String Operations"foo" + "bar""foo"[0]"foo"[:1]"foo".upper()"{0}: {1}".format("foo", "bar")"{foo}: {bar}".format(foo=42, bar=1138)len("foo")
  18. 18. Numeric Types4242.042L
  19. 19. Lists, Tuples, and Sets[a, b, c](Rush, 2112, 5.0)set([a, b, c])
  20. 20. Sequence Operations[...][0][...][-1][...][:1] # same as [...][0:1][...].append(4)[...].extend([4, 5, 6])[...].pop()len([...])
  21. 21. Dictionaries{key1: value1, key2: value2}
  22. 22. Dictionary Operations{...}[key1]{...}.get(key2, default){...}.keys(){...}.values(){...}.items()len({...})
  23. 23. Assignment & Comparisonfoo = barfoo == bazfoo != bazfoo is Nonefoo is not None
  24. 24. Flow Controlif expression: ...elif expression: ...else: ...
  25. 25. Flow Controlfor item in sequence: if expression: continue if expression: break
  26. 26. Flow Controlwhile expression: if expression: continue if expression: break
  27. 27. Functionsdef foo(): return 42def foo(bar): return bardef foo(bar, baz=quux): return (bar, baz)def foo(*args, **kwargs): return (args, kwargs)
  28. 28. Decorators@bardef foo(): return 42@baz(xyzzy)def quux(): return 42
  29. 29. Classesclass Foo(object): def __init__(self, bar): self.bar = bar
  30. 30. Docstrings"Modules can have docstrings."class Foo(object): "Classes can have docstrings too." def __init__(self, bar): "So can functions/methods."
  31. 31. Exceptionstry: raise Exception("OH NOES!")except: log_error() raiseelse: do_some_more()finally: clean_up()
  32. 32. Namespacesimport loggingfrom datetime import timedeltafrom decimal import Decimal as D
  33. 33. Introspection>>> dir(Foo)[__class__, __delattr__, __dict__, __doc__,__format__, __getattribute__, __hash__,__init__, __module__, __new__, __reduce__,__reduce_ex__, __repr__, __setattr__,__sizeof__, __str__, __subclasshook__,__weakref__]
  34. 34. Introspection>>> help(Foo)Help on class Foo in module __main__:class Foo(__builtin__.object) | Classes can have docstrings too. | | Methods defined here: | | __init__(self, bar) | So can functions/methods. | ...-------------------------------------------------------- | Data descriptors defined here:
  35. 35. And more...• Generators • Properties• Generator Expressions • Context Managers• List Comprehensions • Class Decorators• Set Comprehensions • Abstract Base Classes• Dictionary • Metaclasses Comprehensions
  36. 36. Style: PEP-8• No tabs • Line breaks around 78-79 chars• Four-space indents • Some other OCD-• Don’t mix tabs & spaces pleasing ideas :-)• lower_case_methods• CamelCaseClasses
  37. 37. Setup
  38. 38. Environment Setup• Mac or Linux? You’ve already got Python!• You’ll also need Git if you don’t have it; download it from http://git-scm.com or use your package manager to install it• Windows? Well, then...
  39. 39. Windows Setup• Portable Python and Portable Git• Won’t modify your system at all• Can be easily uninstalled• If you want to permanently install Python and Git you can easily do that too
  40. 40. Portable Python 2.7• Download http://bit.ly/13eyQGn http://p.osuosl.org/pub/portablepython/v2.7/PortablePython_2.7.3.1.exe• Run the .EXE• Install into c:django-precompiler• Download wont work? p://p.codemash.org/webdev_with_django
  41. 41. Portable Git• Download http://bit.ly/X4dGps http://msysgit.googlecode.com/files/Git-1.8.0-preview20121022.exe• Create a new folder• Extract archive into a new folder: c:django-precompilerPortable Git 1.8.0-preview20121022• Download wont work? p://p.codemash.org/webdev_with_django
  42. 42. Fixing the Path• Download: https://gist.github.com/4399659• Save it as a file named run-cmd.bat• Run it• Download wont work? p://p.codemash.org/webdev_with_django
  43. 43. Installing Packages• easy_install: easy_install package• pip: pip install package
  44. 44. Installing Packages• Installed packages go into a site-packages directory in your Python lib• That’s the “system Python” by default• But different programs may need different versions of packages...• So we have virtual environments!
  45. 45. Virtual Environments• virtualenv• Creates an isolated Python environment with its own site-packages• Install whatever you want without fouling anything else up
  46. 46. Python 2 or 3?• The future of Python is Python 3• Django 1.5 has experimental Python 3 support• Python 2.7 is still recommended for production applications• Django 1.6 will fully support Python 3
  47. 47. Activate the Virtual Environment# Mac/Linux/etc...$ virtualenv django-precompiler$ cd django-precompiler$ source bin/activate# Windows> python virtualenv django-precompiler> cd django-precompiler> Scripts/activate.bat
  48. 48. The Django Stack
  49. 49. Request DjangoResponse
  50. 50. Request Framework Middleware Django URLs Response Views Models Templates Tags & DB Filters
  51. 51. The Project...
  52. 52. CODE SMASH!• Code Smash is a fictional soware development conference for people who need to punch out awesome code• It needs a website!• We’re going to build one
  53. 53. Starting a Project# Normally...$ git init src# Today...$ git clone https://github.com/finiteloopsoftware/django-precompiler.git src$ cd src$ git reset --hard ex00
  54. 54. Defining Requirements • requirements.txt • A basic example:MyAppFramework==0.9.4Library>=0.2http://someserver.org/packages/MyPackage-3.0.tar.gz
  55. 55. Requirements• Create a requirements.txt• Require Django version 1.5; use: https://www.djangoproject.com/download/1.5c1/tarball/
  56. 56. Installing Requirements$ pip install -r requirements.txt
  57. 57. Starting a Project# Mac/Linux/etc.$ django-admin.py startproject codesmash ./$ python manage.py runserver# Windows> python Scripts/django-admin.py startproject codesmash> python manage.py runserver
  58. 58. New Project Contentssrc/ codesmash/ __init__.py settings.py urls.py wsgi.py manage.py
  59. 59. A Static Home Page
  60. 60. Templates• Make a templates directory under src: $ mkdir templates• Update settings to tell Django where to find the templates• Put an HTML file in the templates directory Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  61. 61. URLs• Map URLs in requests to code that can be executed• Regular expressions!• Subsections of your site can have their own urls.py modules (more on this later) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  62. 62. URLsfrom django.conf.urls import patterns, include, urlurlpatterns = patterns(,    url(r^$, codesmash.views.home, name=home),)
  63. 63. Views• Code that handles requests• Other frameworks oen call these “controllers”• Basically a function that: • gets a request passed to it • returns text or a response Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  64. 64. Viewsfrom django.http import HttpResponsedef my_view(request): return HttpResponse("Hello, world!") Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  65. 65. Viewsfrom django.http import HttpResponsefrom django.template import Context, loaderdef my_view(request): template = loader.get_template(template.html) context = Context({ ... }) return HttpResponse(template.render(context)) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  66. 66. Viewsfrom django.shortcuts import renderdef my_view(request): return render(request, template.html, {...}) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  67. 67. Exercise 1• Create a template for the homepage• Create a view that will respond with the rendered template• Connect the / URL to the view Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  68. 68. Let’s see the code!git reset --hard ex01
  69. 69. Contact Form
  70. 70. Apps• Django believes strongly in separating chunks of a site into apps that can be reused• Ecosystem of reusable apps available• Create an app; from the src directory: $ django-admin.py startapp myapp > python Scripts/django-admin.py startapp myapp Framework Middleware• Add it to INSTALLED_APPS in settings.py URLs Views Tem- Models plates Tags & DB Filters
  71. 71. New App Contentssrc/ codesmash/ myapp/ __init__.py models.py tests.py <-- you should write them! views.py urls.py <-- youll want to make one of these forms.py <-- one of these too Framework Middleware templates/ URLs Views Tem- Models plates Tags & DB Filters
  72. 72. App URLsfrom django.conf.urls import patterns, include, urlurlpatterns = patterns(myapp.views, url(r^$, my_view, name=my_form), ...) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  73. 73. Connecting App URLs# Use include to connect a regex to an apps urls.py# Use namespace to keep app URL names nicely isolatedurlpatterns = patterns(, (r^myapp/, include(myapp.urls, namespace=myapp)), ...) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  74. 74. Form Validation• Why?• Classes for each kind of input field• Form class to gather input fields• View method uses the form class to validate inputs Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  75. 75. A Very Simple Formfrom django import formsclass MyForm(forms.Form): name = forms.CharField(max_length=30) email = forms.EmailField() Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  76. 76. Using a Form in a Viewfrom myapp.forms import MyFormdef my_view(request): form = MyForm(request.POST or None) if request.method == "POST" and form.is_valid(): name = form.cleaned_data[name] email = form.cleaned_data[email] # do something great with that data return render(request, myapp/myform.html, { form: form Framework }) Middleware URLs Views Tem- Models plates Tags & DB Filters
  77. 77. Django Template Language• Call a function or do logic: {% ... %}• Variable substitution: {{ bar }}• Filters: Framework {{ foo|bar }} Middleware URLs Views Tem- Models plates Tags & DB Filters
  78. 78. Forms in Templates<html>... <body> <form action="{% url myapp:my_form %}" method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Go!</button> </form> Framework </body> Middleware</html> URLs Views Tem- Models plates Tags & DB Filters
  79. 79. Sending Mail• Add an EMAIL_BACKEND in settings.py EMAIL_BACKEND = django.core.mail.backends.console.EmailBackend• Import and use from django.core.mail import send_mail send_mail(subject, message, sender, [recipient, ...]) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  80. 80. Exercise 2• Create a contact app• Create a contact form with subject, message, and sender’s email address• Create view to display and process the form and “send” the message• Connect the view to “/contact” URL Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  81. 81. Let’s see the code!git reset --hard ex02
  82. 82. Redirecting on Success• Make the POST action redirect with a GET on successful processing• Avoid “resubmit form” issues when reloading or returning to success page (browser back button) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  83. 83. Redirectingfrom django.shortcuts import redirectdef my_view(request): ... return redirect(namespace:name) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  84. 84. Exercise 3• Make a separate contact form URL and template for displaying a success message• Update the POST handler to redirect to the success page Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  85. 85. Let’s see the code!git reset --hard ex03
  86. 86. A Consistent Appearance
  87. 87. Template Inheritance• Define a base template for the site• Other templates extend the base template• Blocks allow child templates to inject content into areas of the parent template Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  88. 88. base.html<!DOCTYPE html><html> <head> <meta name="..." content="..."> <title>{% block title %}My Site{% endblock %}</title> </head> <body> {% block content %} {% endblock %} </body> Framework</html> Middleware URLs Views Tem- Models plates Tags & DB Filters
  89. 89. helloworld.html{% extends "base.html" %}{% block title %}Hello, World{% endblock %}{% block content %} <h1>Hey! Great!</h1> <p>Sure is some lovely content right here.</p> <p>Yup.</p>{% endblock %} Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  90. 90. Exercise 4• Refactor those templates!• Make a base.html with appropriate blocks• Make other templates extend it and fill in the blocks Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  91. 91. Let’s see the code!git reset --hard ex04
  92. 92. User Registration
  93. 93. No Need to Reinvent• Django comes with a robust user framework: django.contrib.auth• Registration• Login/Logout• Password Recovery Framework• Etc. Middleware URLs Views Tem- Models plates Tags & DB Filters
  94. 94. Database Settingsimport osPROJECT_ROOT = os.path.abspath( os.path.join(os.path.dirname(__file__), ".."))DATABASES = { default: { ENGINE: django.db.backends.sqlite3, NAME: os.path.join( PROJECT_ROOT, "database.db") Framework } Middleware} URLs Views Tem- Models plates Tags & DB Filters
  95. 95. Create the Database$ python manage.py syncdb Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  96. 96. Extend the UserCreationFormfrom django.contrib.auth.forms import UserCreationFormclass RegistrationForm(UserCreationForm): class Meta(UserCreationForm.Meta): fields = ("username", "email") Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  97. 97. Register the Userform = RegistrationForm(request.POST)if form.is_valid(): form.save() Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  98. 98. Login Aer Registrationfrom django.contrib.auth import authenticate, loginuser = authenticate( username=form.cleaned_data[username], password=form.cleaned_data[password1])login(request, user) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  99. 99. The User Object• Always have one in every request• Always available to templates• Can be anonymous or populated depending on whether the user has authenticated
  100. 100. Exercise 5• Start a new app called • Profile page should just “accounts” display username and email• Set up a UserCreationForm • Set up templates for the subclass in accounts.forms form and profile page in with username and email templates/accounts/• Set up a view that displays • Wire up the URLs (be sure to the form on GET give them names)• Make the view handle POSTs • Link to registration from the Framework – check the form, register the header Middleware user, log in, and redirect to a user profile page URLs Views Tem- Models plates Tags & DB Filters
  101. 101. Let’s see the code!git reset --hard ex05
  102. 102. User Login & Logout
  103. 103. More Reusable Goodness• django.contrib.auth provides URLs and views for login and logout• Will want to provide our own templates Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  104. 104. URLsurlpatterns = patterns(, ... (rauth/, include(django.contrib.auth.urls, namespace=auth)), ...) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  105. 105. Templates to Override• templates/registration/login.html• templates/registration/logged_out.html Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  106. 106. Login/Logout Links{% url auth:login %}{% url auth:logout %} Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  107. 107. Differentiate Logged In/Out{% if user.is_authenticated %} ...{% else %} ...{% endif %} Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  108. 108. Exercise 6• Enable auth URLs • Show username in header when user is• Add login and logout logged in links to the site header • Link to user profile when• Show login when user is user is logged in logged out, logout when user is logged in • Customize login and logout pages Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  109. 109. Let’s see the code!git reset --hard ex06
  110. 110. Django Admin
  111. 111. Django Admin• Free CRUD!• Navigate database data by model• Make changes• Highly customizable Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  112. 112. Enabling the Admin App• Uncomment admin lines from INSTALLED_APPS in settings.py• Uncomment admin lines from the project’s urls.py• Mini-exercise: go do that :-) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  113. 113. Demo Time!git reset --hard ex07
  114. 114. CMS Pages
  115. 115. django.contrib.flatpages• Store simple “flat” HTML pages in the database• Has a URL, title, and content• Useful for one-off pages with no logic that don’t deserve full apps• Add/edit content via the admin app Framework Middleware• Let’s enable it now! URLs Views Tem- Models plates Tags & DB Filters
  116. 116. settings.py• Add to INSTALLED_APPS: django.contrib.flatpages• Add to MIDDLEWARE_CLASSES: django.contrib.flatpages.middleware.FlatpageFallback Middleware Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  117. 117. urls.py•Change root URL to use flatpage:url(r^$, django.contrib.flatpages.views.flatpage, {url: / }, name=home) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  118. 118. Make a Flatpage Template• Put it in templates/flatpages/default.html• In the title block, add: {{ flatpage.title }}• In the content block, add: {{ flatpage.content }} Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  119. 119. Let’s see the code!git reset --hard ex08
  120. 120. Meanwhile, in the admin app...
  121. 121. Conference Talks:An App with a Custom Data Model
  122. 122. Models• Model classes are the nouns of the system• Used to create database tables• Integrated with the ORM to interact with the database• Need to `python manage.py syncdb` when adding a new model class Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  123. 123. Modelsfrom django.db import modelsclass Thingy(models.Model): name = models.CharField(max_length=255) awesome = models.BooleanField(default=True) description = models.TextField(blank=True) def __str__(self): return self.name Framework Middleware def __unicode__(self): # note: not in Python 3 return unicode(str(self)) URLs Views Tem- Models plates Tags & DB Filters
  124. 124. Exercise 9• Create a “talks” app to manage talks• Create a Talk model; it should have: • title - up to 255 characters • approved - true or false, default false • recording_release - true or false, default false • abstract - text describing the talk Framework • outline - text outlining the talk Middleware URLs • notes - text about the talk that wont be public Views Tem- Models plates Tags & DB Filters
  125. 125. Let’s see the code!git reset --hard ex09
  126. 126. Wiring the Model for Admin Access • Each app manages its own admin wiring • Goes into an admin.py within the app Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  127. 127. admin.pyfrom django.contrib import adminfrom myapp.models import Thingyadmin.site.register(Thingy) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  128. 128. Exercise 10• Create an admin.py for the talks app• Register the Talk model• Start up the admin app and verify that Talks appears Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  129. 129. Let’s see the code!git reset --hard ex10
  130. 130. Pluralize All the Thingys!class Thingy(model.models): ... class Meta: verbose_name_plural = "Thingies" Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  131. 131. Relations• Foreign key (one-to-many)• Many-to-many Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  132. 132. Foreign Key Relationsclass Thingy(models.Model): ...class Gadget(models.Model): ...class Gizmo(models.Model): thingy = models.ForeignKey(Thingy) gadget = models.ForeignKey(Gadget, blank=True, null=True) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  133. 133. Many-to-Many Relationsclass Thingy(models.Model): ...class Gizmo(models.Model): thingies = models.ManyToManyField(Thingy) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  134. 134. Saving a Model Objectthingy = Thingy()thingy.size = bigthingy.save()gadget = Gadget(thingy=thingy)gadget.save()gizmo = Gizmo(thingies=[thingy])gizmo.save() Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  135. 135. Exercise 11• Create new model classes • All should have a name, up for foreign keys: to 255 characters • Category • All should have a __str__; Time Slot’s should use • Talk Type strime (see strime.net) • Audience Skill Level • Location and Time Slot should be optional • Location • Do a many-to-many on Framework django.contrib.auth.models. Middleware • Time Slot User for talk speakers URLs Views Tem- Models plates Tags & DB Filters
  136. 136. Let’s see the code!git reset --hard ex11
  137. 137. Meanwhile, in the admin app...
  138. 138. Changing Existing Models• Adding/removing/changing fields in a model requires a schema migration• Django doesn’t support it out of the box• Pro mode: use South Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  139. 139. Cheesy Precompiler Way $ ./manage.py dbshell > DROP TABLE talks; $ ./manage.py syncdb Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  140. 140. Querying the Modelall_thingies = Thingy.objects.all()single_thingy = Thingy.objects.get(id=1)big_thingies = Thingy.objects.filter(size=big)ordered_thingies = Thingy.objects.all().order_by(size) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  141. 141. Relations in Templates• When a model object retrieved from the ORM has relations, you get a relation manager and not an actual iterable collection• Need to call .all() (or get or filter) on it before you get back the related model objects Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  142. 142. Relations in Templates{% for gizmo in gizmos %} {% for thingy in gizmo.thingies.all %} ... {% endfor %}{% endfor %} Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  143. 143. Exercise 12• Create a view and template to display a list of all talks, ordered by title• Be sure to display all of the talk speakers Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  144. 144. Let’s see the code!git reset --hard ex12
  145. 145. Optimizing Queries• What we just did will make lots of extra database queries (because of the loops)• Go read up on: • select_related: does a join in SQL • prefetch_related: queries in advance, caches results, allows “join” in Python
  146. 146. Model Managers• A place to encapsulate data queries• Extend to provide extra queries with developer-friendly interfaces Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  147. 147. Model Managersclass ThingyManager(models.Manager): def big_ones(self): return self.get_query_set().filter(size=big) def of_color(self, color): return self.get_query_set().filter(color=color)class Thingy(models.Model): Framework objects = ThingyManager() Middleware URLs Views Tem- Models plates Tags & DB Filters
  148. 148. Using a Model Managerbig_thingies = Thingy.objects.big_ones()green_thingies = Thingy.objects.of_color(green) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  149. 149. Exercise 13• Move the queries from the previous exercise into a TalkManager• Change the queries to only get talks that have been approved Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  150. 150. Let’s see the code!git reset --hard ex13
  151. 151. Generic Views• Many views fall into the same patterns• Django provides generic view classes for things like showing a list of objects, creating an object, updating an object, deleting, etc.• Subclass and set properties or override certain methods to customize Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  152. 152. Generic List Viewsfrom django.views.generic import ListViewclass ThingyListView(ListView): queryset = Thingy.objects.all() Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  153. 153. Generic List View URLsfrom django.conf.urls import patterns, include, urlfrom myapp.views import ThingyListViewurlpatterns = patterns(myapp.views, ... url(r^$, ThingyListView.as_view(), name=things) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  154. 154. Generic List View Templates• Generic List Views are automatically wired to templates• Naming convention: lowercase model name + “_list.html”, eg: templates/myapp/thingy_list.html Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  155. 155. Exercise 14• Replace the view that lists talks with a generic list view• Redo the URL mapping to use your new generic list view subclass Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  156. 156. Let’s see the code!git reset --hard ex14
  157. 157. Can You Guess What’s Next?• Need to create new talks• We could do it the hard way... • Make a Form • Make a View • Read validated data, put it into a model object Framework • Save the model, redirect... Middleware URLs Views Tem- Models plates Tags & DB Filters
  158. 158. Model Formsfrom django import formsfrom myapp.models import Thingyclass ThingyForm(forms.ModelForm): class Meta: model = Thingy exclude = (flavor, user) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  159. 159. Generic Create Viewsfrom django.views.generic.edit import CreateViewfrom myapp.forms import ThingyFormclass ThingyCreationView(CreateView): model = Thingy form_class = ThingyForm success_url = "/accounts/profile" Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  160. 160. Generic Create View Templates• Generic Create Views are automatically wired to templates• Naming convention: lowercase model name + “_form.html”; eg: templates/myapp/thingy_form.html Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  161. 161. Exercise 15• Make a Generic Create • Be sure to connect a View and Model Form to “create” URL to the new submit new talk Generic Create View proposals • Don’t forget a template!• Exclude approval status, location, and time slot • Link to the create form (since the speaker from user profile doesn’t control them) • List user’s submitted Framework talks on user profile Middleware URLs Views Tem- Models plates Tags & DB Filters
  162. 162. Let’s see the code!git reset --hard ex15
  163. 163. Generic Edit Viewsfrom django.shortcuts import resolve_urlfrom django.view.generic.edit import UpdateViewfrom myapp.forms import ThingyFormclass ThingyUpdateView(UpdateView): form_class = ThingyForm queryset = Thingy.objects.all() def get_success_url(self): return resolve_url(myapp:thingy) def get_context_data(self, **kwargs): Framework context = super(ThingyUpdateView, self).get_context_data(**kwargs) context[editing] = True Middleware return context URLs Views Tem- Models plates Tags & DB Filters
  164. 164. Generic Edit View URLsfrom django.conf.urls import patterns, include, urlfrom myapp.views import ThingyUpdateViewurlpatterns = patterns(myapp.views, ... url(r(?P<pk>[0-9]+)$, ThingyUpdateView.as_view(), name=update),) Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  165. 165. Exercise 16• Create a Generic Edit View for talks• Use the Model Form from the previous exercise• Be sure to wire it to a URL for editing• Change the existing template to indicate whether we’re editing or creating Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  166. 166. Let’s see the code!git reset --hard ex16
  167. 167. Security in Views• Can you spot a security problem in the previous exercise?• Anyone can edit any talk!• Generic views can restrict access by limiting the queryset available in the view Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  168. 168. Restricting Object Access# In models.py...class ThingyManager(models.Manager): def for_user(self, user): return self.get_query_set().filter(user=user)# In views.py...class ThingyUpdateView(UpdateView): def get_queryset(self): Framework return Thingy.objects.for_user( Middleware self.request.user) URLs Views Tem- Models plates Tags & DB Filters
  169. 169. Exercise 17• Lock down the update view from the previous exercise so that a talk may only be edited by its speakers Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  170. 170. Let’s see the code!git reset --hard ex17
  171. 171. Read-Only Data in Generic Edit Views • Model Form automatically builds form elements for everything in the model • Model Form excludes anything that it was told to exclude • Excluded fields are still available as attributes of a variable called “object” (the Framework object being displayed/edited) Middleware URLs Views Tem- Models plates Tags & DB Filters
  172. 172. Read-Only Data in Generic Edit Views<form ...> {% csrf_token %} {{ form.as_p }} <p><input type="text" id="flavor" value="{{ object.flavor }}" disabled ></p> <input type="submit" value="Save Changes"></form> Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  173. 173. Exercise 18• Change the talk form from the previous exercises• Show time slot, location, and approval status without allowing them to be modified Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  174. 174. Let’s see the code!git reset --hard ex18
  175. 175. Requiring Loginfrom django.contrib.auth.decorators import login_required@login_requireddef my_login_only_view(request): return render(request, "myapp/my_view.html") Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  176. 176. Exercise 19• Require login on the user profile page Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  177. 177. Let’s see the code!git reset --hard ex19
  178. 178. Custom Template Filters• Django comes with many filters• You can add your own• Function that accepts a value and returns a string Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  179. 179. Defining a Custom Filter# In myapp/templatetags/myfilters.py...from django import templatefrom django.utils.html import format_htmlregister = template.Library()@register.filterdef my_filter(value): ... Framework return format_html("...") Middleware URLs Views Tem- Models plates Tags & DB Filters
  180. 180. Using a Custom Filter{% load myfilters %}{% block content %} <p>{{ foo|my_filter }}</p> <p>{{ bar }}</p>{% endblock %} Framework Middleware URLs Views Tem- Models plates Tags & DB Filters
  181. 181. Exercise 20• Create a custom filter function “boolean_icon” that will show one image if a value is True and another if it’s False• Use the boolean_icon in the user’s profile to indicate whether a talk has been approved• Use static icons from the admin site: Framework from django.contrib.admin.templatetags.admin_static import static Middleware icon_url = static(admin/img/icon-{0}.gif.format( URLs {True: yes, False: no, None: unknown}[value]) Views Tem- Models plates Tags & DB Filters
  182. 182. Let’s see the code!git reset --hard ex20
  183. 183. Bonus Exercises• Show talks by time slot and/or location• Blog; include RSS feed• Sponsorship; include sponsor image upload and display• Enhance user profiles; include image upload, default to Gravatar Framework Middleware• Room swap/ticket swap URLs Views Tem- Models plates Tags & DB Filters
  184. 184. A Little Bit About Deployment
  185. 185. Django
  186. 186. Varnish NginxStatic Files Gunicorn Django Django Django
  187. 187. Where to Deploy• Gondor.io• Heroku• Webfaction• Google App Engine (if that’s what you’re into)• Your favorite VPS (Rackspace, AWS, etc.)
  188. 188. Questions?
  189. 189. Links• http://python.org• https://djangoproject.com• https://github.com/finiteloopsoware/ django-precompiler
  190. 190. Credits• Image from Django Unchained by Sony Pictures http://www.nydailynews.com/entertainment/tv-movies/django-star-foxx-life- built-race-article-1.1220275• Image of Django Reinhardt by ~Raimondsy http://raimondsy.deviantart.com/art/Django-Reinhardt-314914547• Other images from ClipArt Etc. http://etc.usf.edu/clipart/
  191. 191. Contact Information Mike Crute David Stanek Finite Loop Soware American Greetings http://mike.crute.org http://traceback.org @mcrute @dstanek Mike Pirnat American Greetings http://mike.pirnat.com @mpirnat
  192. 192. Thanks for coming & happy hacking!
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×