SlideShare a Scribd company logo
Introduction to Django

Jacob Kaplan-Moss

Strange Loop 2011
http://lanyrd.com/sfypm
Django Training

Part 1: Introduction to Django.
“Django is a high-level
Python web framework
 that encourages rapid
development and clean,



                     ”
   pragmatic design.


                          2
“Django is a high-level
Python web framework
 that encourages rapid
development and clean,



                     ”
   pragmatic design.


                          3
“Django is a high-level
Python web framework
 that encourages rapid
development and clean,



                     ”
   pragmatic design.


                          4
“Django is a high-level
Python web framework
 that encourages rapid
development and clean,



                     ”
   pragmatic design.


                          5
Documentation
           http://django.me/design
http://www.djangobook.com/en/2.0/chapter01/




                                              6
Which Django version
   should I use?


                       7
Installing Django

• Download and run http://bit.ly/dsetup
 (http://python-­‐distribute.org/distribute_setup.py)

• easy_install  Django
• Later: learn about pip and virtualenv
  http://pip.rtfd.org/
  http://virtualenv.rtfd.org/



                                                        8
“Projects”



             9
$  django-­‐admin.py  startproject  yabl




                                           10
yabl/
   __init__.py
   manage.py
   settings.py
   urls.py




                 11
$  python  manage.py  runserver
Validating  models...
0  errors  found.

Django  version  1.1  beta  1  SVN-­‐10844,  using  settings  'yabl.settings'
Development  server  is  running  at  http://127.0.0.1:8000/
Quit  the  server  with  CONTROL-­‐C.




                                                                                12
13
Project settings

• DATABASE_ENGINE
• DATABASE_NAME
• DATABASE_USER
• DATABASE_PASSWORD
• DATABASE_HOST


                      14
$  python  manage.py  syncdb
Creating  table  auth_permission
Creating  table  auth_group
Creating  table  auth_user
Creating  table  auth_message
Creating  table  django_content_type
Creating  table  django_session
Creating  table  django_site

You  just  installed  Django's  auth  system,  
which  means  you  don't  have  any  superusers  defined.
Would  you  like  to  create  one  now?  (yes/no):  yes
Username  (Leave  blank  to  use  'jacob'):  jacob
E-­‐mail  address:  jacob@jacobian.org
Password:  
Password  (again):  
Superuser  created  successfully.
Installing  index  for  auth.Permission  model
Installing  index  for  auth.Message  model


                                                            15
Documentation
http://django.me/about-settings
    http://django.me/settings
  http://django.me/manage.py




                                  16
Exercise:
  “it worked!”




                 17
Django Training

Part 2: Apps, models, and the admin
“Apps”



         2
“Models”



           3
What’s a model?



                  4
MVC?
(Model-View-Controller)




                          5
CREATE  TABLE  "entries_entry"  (
        "id"  integer  NOT  NULL  PRIMARY  KEY,
        "author_id"  integer  NOT  NULL,
        "pub_date"  datetime  NOT  NULL,
        "headline"  varchar(200)  NOT  NULL,
        "slug"  varchar(50)  NOT  NULL  UNIQUE,
        "summary"  text  NOT  NULL,
        "body"  text  NOT  NULL
)




                                                  6
Scary Quirky Language

• SQL is tough
• SQL knows no version control
• DRY
• Python is fun!



                                 7
import  datetime
from  django.db  import  models
from  yabl.authors.models  import  Author

class  Entry(models.Model):
        author              =  models.ForeignKey(Author,  related_name='entries')
        pub_date          =  models.DateTimeField(default=datetime.datetime.now)
        headline          =  models.CharField(max_length=200)
        slug                  =  models.SlugField(unique=True)
        summary            =  models.TextField()
        body                  =  models.TextField()




                                                                                    8
Defining Models



                 9
$  python  manage.py  startapp  authors




                                          10
authors/
   __init__.py
   models.py
   tests.py
   views.py




                 11
INSTALLED_APPS  =  (
        "django.contrib.auth",
        "django.contrib.contenttypes",
        "django.contrib.sessions",  
        "django.contrib.sites",
        "yabl.authors",
)




                                         12
from  django.db  import  models

class  Author(models.Model):
        first_name    =  models.CharField(max_length=200)
        last_name      =  models.CharField(max_length=200)
        bio                  =  models.TextField(blank=True)




                                                               13
$  python  manage.py  validate
0  errors  found.




                                 14
$  python  manage.py  sqlall  authors
BEGIN;
CREATE  TABLE  "authors_author"  (
        "id"  integer  NOT  NULL  PRIMARY  KEY,
        "first_name"  varchar(200)  NOT  NULL,
        "last_name"  varchar(200)  NOT  NULL,
        "bio"  text  NOT  NULL
);
COMMIT;




                                                  15
$  python  manage.py  syncdb
Creating  table  authors_author
Installing  index  for  authors.Author  model




                                                16
$  python  manage.py  shell

[1]  >>>  from  yabl.authors.models  import  Author

[2]  >>>  a  =  Author(first_name="John",  last_name="Barth")

[3]  >>>  a.save()




                                                                17
[4]  >>>  Author.objects.all()
[4]      :  [<Author:  Author  object>]

[5]  >>>  Author.objects.create(first_name='Miguel',  last_name='de  Cervantes')
[5]      :  <Author:  Author  object>

[6]  >>>  Author.objects.all()
[6]      :  [<Author:  Author  object>,  <Author:  Author  object>]

[7]  >>>  al  =  Author.objects.filter(first_name='John')

[8]  >>>  al[0].last_name
[8]      :  u'Barth'

[9]  >>>  Author.objects.get(last_name__startswith='de').first_name
[9]      :  u'Miguel'




                                                                                   18
Model metadata



                 19
class  Author(models.Model):
        first_name    =  models.CharField(max_length=200)
        last_name      =  models.CharField(max_length=200)
        bio                  =  models.TextField(blank=True)
        
        def  __unicode__(self):
                return  '%s  %s'  %  (self.first_name,  self.last_name)




                                                                          20
class  Author(models.Model):
        …

        class  Meta:
                verbose_name_plural  =  'authors'
                ordering  =  ['last_name',  'first_name']




                                                            21
[1]  >>>  from  yabl.authors.models  import  Author

[2]  >>>  Author.objects.all()
[2]      :  [<Author:  John  Barth>,  <Author:  Miguel  de  Cervantes>]

[3]  >>>  Author.objects.order_by('-­‐first_name')
[3]      :  [<Author:  Miguel  de  Cervantes>,  <Author:  John  Barth>]




                                                                          22
Documentation
          http://django.me/models
http://www.djangobook.com/en/2.0/chapter05/




                                              23
Exercise:
            Write some apps and some models:


• Author (authors app)       • Entry (entries app)
  • first_name (CharField)      • author (ForeignKey)
  • last_name (CharField)      • pub_date (DateTimeField)
  • bio (TextField)            • is_published (BooleanField)
                               • headline (CharField)
                               • slug (SlugField)
                               • summary (TextField)
                               • body (TextField)




                                                               24
Django’s
admin interface


                  25
“ A Web-based interface,
   limited to trusted site
administrators, that enables
  the adding, editing and




                                           ”
  deletion of site content.

             — The Django Book
            http://djangobook.com/en/2.0/chapter06/

                                                      26
from  django.contrib  import  admin
from  yabl.authors.models  import  Author

admin.site.register(Author)




                                            27
INSTALLED_APPS  =  (
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.sites',
        'django.contrib.admin',
        'yabl.authors',
        'yabl.entries',
)




                                         28
$  python  manage.py  syncdb
Creating  table  django_admin_log
Installing  index  for  admin.LogEntry  model




                                                29
from  django.conf.urls.defaults  import  *

#  Uncomment  the  next  two  lines  to  enable  the  admin:
from  django.contrib  import  admin
admin.autodiscover()

urlpatterns  =  patterns('',
        #  Example:
        #  (r'^yabl/',  include('yabl.foo.urls')),

        #  Uncomment  the  admin/doc  line  below  and  add  'django.contrib.admindocs'  
        #  to  INSTALLED_APPS  to  enable  admin  documentation:
        #  (r'^admin/doc/',  include('django.contrib.admindocs.urls')),

        #  Uncomment  the  next  line  to  enable  the  admin:
        (r'^admin/',  include(admin.site.urls)),
)




                                                                                            30
31
32
33
34
from  django.contrib  import  admin
from  yabl.authors.models  import  Author

class  AuthorAdmin(admin.ModelAdmin):
        pass

admin.site.register(Author,  AuthorAdmin)




                                            35
Documentation
http://djangobook.com/en/2.0/chapter06/
          http://django.me/admin




                                          36
Exercise:




            37
Django Training

Part 3: URLs, views, and templates
Views



        2
What’s a view?



                 3
4
URLs



       5
page.php

script.cgi?pageid=144

   StoryPage.aspx
                        6
0,2097,1-1-30-72-407-4752,00.html




                                    7
/authors/
/authors/jacob/
/authors/adrian/


                   8
ROOT_URLCONF  =  "yabl.urls"




                               9
yabl/urls.py

from  django.conf.urls.defaults  import  *

#  Uncomment  the  next  two  lines  to  enable  the  admin:
from  django.contrib  import  admin
admin.autodiscover()

urlpatterns  =  patterns('',
        (r'^authors/$',                  'yabl.authors.views.author_list'),
        (r'^authors/(d+)/$',      'yabl.authors.views.author_detail'),
        (r'^admin/',  include(admin.site.urls)),
)



                                                                              10
yabl/authors/urls.py


from  django.conf.urls.defaults  import  *

urlpatterns  =  patterns('',
        (r'^$',                  'yabl.authors.views.author_list'),
        (r'^(d+)/$',      'yabl.authors.views.author_detail'),
)




                                                                      11
yabl/urls.py

from  django.conf.urls.defaults  import  *

#  Uncomment  the  next  two  lines  to  enable  the  admin:
from  django.contrib  import  admin
admin.autodiscover()

urlpatterns  =  patterns('',
        (r'^authors/',  include('yabl.authors.urls')),
        (r'^admin/',      include(admin.site.urls)),
)




                                                               12
Regex crash course
a                    The letter “a”.
a+                   One or more “a”s.
b?                   Zero or one “b”s.
c{1,3}               One, two, or three “c”s.
.                    Any single character.
[abc]                Either an “a”, “b”, or “c”.
[A-­‐Z]              Any character between “A” and “Z”.
[A-­‐Za-­‐z0-­‐9]?   Zero or one letters “A-Z”, “a-z”, or “0-9”.
(d{3,4})            A group containing three or four digits.
(w*)                A group containing zero or more word characters (letters/digits).
[^/]+                One or more characters until (and not including) a forward slash.
^(joe|bob)           A string starting with “joe” or “bob”.
(?P<id>d+)          A group named “id” containing one or more digits.
article/$            A string ending with “article/”

                                                                                         13
Dissecting a request
• GET  /authors/1/
• ROOT_URLCONF
• yabl.urls
• (r'^authors/',  include('yabl.authors.urls'))
• yabl.authors.urls
• (r'^$',  'author_list')                    (no match)
• (r'^(d+)/',  'author_detail')      (match!)
• author_detail(request,  '1')
                                                          14
Documentation
  http://django.me/urls




                          15
A first view



              16
yabl/authors/views.py


from  django.http  import  HttpResponse

def  author_list(request):
        return  HttpResponse("This  is  the  author  list!")




                                                               17
yabl/authors/views.py

from  django.http  import  HttpResponse
from  yabl.authors.models  import  Author

def  author_list(request):
        r  =  "<ul>"
        for  a  in  Author.objects.all():
                r  +=  "<li>%s</li>"  %  a.name
        r  +=  "</ul>"
        return  HttpResponse(r)




                                                  18
yabl/authors/views.py

from  django  import  template
from  django.http  import  HttpResponse
from  yabl.authors.models  import  Author

def  author_list(request):
        as  =  Author.objects.all()
        tmpl  =  template.loader.get_template("authors/index.html")
        context  =  template.Context({"authors":  as})
        return  HttpResponse(tmpl.render(context))




                                                                      19
yabl/authors/views.py


from  django.shortcuts  import  render
from  yabl.authors.models  import  Author

def  author_list(request):
        context  =  {"authors"  :  Author.objects.all()}
        return  render(request,  "authors/index.html",  context)




                                                                   20
yabl/authors/views.py

from  django.http  import  Http404
from  django.shortcuts  import  render_to_response
from  yabl.authors.models  import  Author

def  author_detail(request,  author_id):
        try:
                author  =  Author.objects.get(id=author_id)
        except  Author.DoesNotExist:
                raise  Http404()

        return  render(request,  "authors/detail.html",  {"author"  :  author})



                                                                                  21
yabl/authors/views.py


from  django.shortcuts  import  render_to_response,  get_object_or_404
from  yabl.authors.models  import  Author

def  author_detail(request,  author_id):
        author  =  get_object_or_404(Author,  id=author_id)
        return  render(request,  "authors/detail.html",  {"author"  :  author})




                                                                                  22
Templates



            23
What’s a template?



                     24
<!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN">
<html  lang="en">
<head><title>Authors</title></head>
<body>
   <h1>Authors  ({{  authors|length  }}  total)</h1>
   <ul>
      {%  for  a  in  authors  %}
          <li>
             <a  href="{{  a.id  }}/">{{  a.name  }}</a>
          </li>
      {%  endfor  %}
   </ul>
</body>
</html>




                                                            25
Where to templates go?

• In an app’s templates directory.
• In directories specified by
  settings.TEMPLATE_DIRS.
• ...



                                     26
TEMPLATE_DIRS  =  [
        '/path/to/some/templates/',
        '/path/to/some/more/other/templates/',
]




                                                 27
TEMPLATE_DIRS  =  [
        '/Users/jacob/Projects/stl-­‐django/yabl/templates/',
]




                                                                28
<!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN">
<html  lang="en">
<head><title>Authors</title></head>
<body>
   <h1>Authors  ({{  authors|length  }}  total)</h1>
   <ul>
      {%  for  a  in  authors  %}
          <li>
             <a  href="{{  a.id  }}/">{{  a.name  }}</a>
          </li>
      {%  endfor  %}
   </ul>
</body>
</html>




                                                            29
The magic dot


• a["name"]
• a.name
• a.name()




                30
<!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN">
<html  lang="en">
<head><title>Authors</title></head>
<body>
   <h1>Authors  ({{  authors|length  }}  total)</h1>
   <ul>
      {%  for  a  in  authors  %}
          <li>
             <a  href="{{  a.id  }}/">{{  a.name  }}</a>
          </li>
      {%  endfor  %}
   </ul>
</body>
</html>




                                                            31
{{  text|escape|linkbreaks  }}




                                 32
{{  text|truncatewords:"30"  }}




                                  33
<!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN">
<html  lang="en">
<head><title>Authors</title></head>
<body>
   <h1>Authors  ({{  authors|length  }}  total)</h1>
   <ul>
      {%  for  a  in  authors  %}
          <li>
             <a  href="{{  a.id  }}/">{{  a.name  }}</a>
          </li>
      {%  endfor  %}
   </ul>
</body>
</html>




                                                            34
Template inheritance



                       35
<!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN">
<html  lang="en">
<head>
   <title>
      {%  block  title  %}YABL{%  endblock  %}
   </title>
</head>
<body>
   <div  id="content">
      {%  block  content  %}{%  endblock  %}
   </div>
   <div  id="footer">
      {%  block  footer  %}Copyright  blah..{%  endblock  %}
   </div>
</body>
</html>




                                                               36
<!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN">
<html  lang="en">
<head>
   <title>
      {%  block  title  %}YABL{%  endblock  %}
   </title>
</head>
<body>
   <div  id="content">
      {%  block  content  %}{%  endblock  %}
   </div>
   <div  id="footer">
      {%  block  footer  %}Copyright  blah..{%  endblock  %}
   </div>
</body>
</html>




                                                               37
{%  extends  "base.html"  %}

{%  block  title  %}
    Authors  |  {{  block.super  }}
{%  endblock  %}

{%  block  content  %}
    <h1>Authors  ({{  authors|length  }}  total)</h1>
    <ul>
       {%  for  a  in  authors  %}
           <li>
              <a  href="{{  a.id  }}/">{{  a.name  }}</a>
           </li>
       {%  endfor  %}
    </ul>
{%  endblock  %}




                                                            38
!                                 "

                                                                        93&45;
!"#$%&$'()#*+,)$-.$'$/0123&45*#"6         !"#$%&$'()#*+,)$23&45*#"6
                                                                        93$,(;
                                                                        ##9&0&5$;
!"#+5718#&0&5$#"6
##!!#)$1&07'2&0&5$#66
                                      $   !"#+5718#&0&5$#"6
                                          ##ABC7/5(2174
                                                                        ####!"#+5718#&0&5$#"6!"#$'(+5718#"6
                                                                        ##9<&0&5$;
!"#$'(+5718#"6                            !"#$'(+5718#"6
                                                                        9<3$,(;
                                                                        9+7(>;
!"#+5718#17'&$'&#"6                       !"#+5718#/,05#"6
                                                                        ##9(0G#0(H*/,05*;
##93:;!!#)$1&07'2&0&5$#669<3:;            ##9D5;
                                                                        ####!"#+5718#/,05#"6!"#$'(+5718#"6
##!"#=7/#)&7/>#0'#)&7/>-50)&#"6           ####950;E74$9<50;
                                                                        ##9<(0G;
####93?;!!#)&7/>23$,(50'$#669<3?;         ####950;A71,5#'$F)9<50;
                                                                        ##9(0G#0(H*17'&$'&*;
####9@;!!#)&7/>2&$,)$#66                  ####222
                                                                        ####!"#+5718#17'&$'&#"6!"#$'(+5718#"6
##!"#$'(=7/#"6                            ##9<D5;
                                                                        ##9<(0G;
!"#$'(+5718#"6                            !"#$'(+5718#"6
                                                                        9<+7(>;
                 section_index.html                 base_generic.html   9<3&45;                      base.html



                                      #



                                                                                                            39
Why?



       40
Inheritance tips
• {% extends %} must be the first thing in
  your template.
• More {% block %}s are better.
• If you’re duplicating content, you’re
  missing a block.
• {{ block.super }}


                                            41
Documentation
http://djangobook.com/en/2.0/chapter04/
        http://django.me/templates




                                          42
Exercise:
   /authors/
 /authors/{id}/

    /entries/
 /entries/{slug}/



                    43
Django training

BONUS: Models and queries
Terminology



              2
Models
a.k.a. “DDL”




               3
Managers
 a.k.a. “table”




                  4
QuerySets
 a.k.a. “selection”




                      5
Model instances
     a.k.a. “row”




                    6
!!!"!"#$#%&'()*+,-./'"*012'.(31"456,21"7.8$9(6.:
!!!"!"
#$%&'()*"+,&"-.'/0"123!4"$%&'()*"523"-.'/0"6,&!7

!!!".#$#!";<=
!!!".
$%&'()*"+,&"-.'/0"123!




  Model      Manager     QuerySet    Instance


                                                   7
Models



         8
Instance methods

class  Entry(models.Model):
        …

        def  is_by_jacob(self):
                return  "jacob"  in  self.author.name.lower()

…

[1]  >>>  e  =  Entry.objects.get(pk=1)

[2]  >>>  e.is_by_jacob()
[2]      :  False


                                                                9
“Special” instance methods




                             10
__unicode__

class  Entry(models.Model):
        …

        def  __unicode__(self):
                return  self.headline

…

[1]  >>>  Entry.objects.all()
[1]      :  [<Entry:  Man  bites  dog>,  <Entry:  Dog  bites  man>]




                                                                      11
save


class  Entry(models.Model):
        …

        def  save(self,  **kwargs):
                self.word_count  =  count_words(self.body)
                super(Entry,  self).save(**kwargs)




                                                             12
save


class  Entry(models.Model):
        …

        def  save(self,  **kwargs):
                self.word_count  =  count_words(self.body)
                super(Entry,  self).save(**kwargs)



                              Don’t forget this part!

                                                             13
delete


class  Author(models.Model):
        …

        def  delete(self):
                nobody  =  Author.objects.get(first_name='<NOBODY>')
                self.entries.update(author=nobody)
                super(Author,  self).delete()




                                                                       14
Managers



           15
Default manager

class  Entry(models.Model):
        …

        objects  =  models.Manager()

…

[1]  >>>  from  yabl.entries.models  import  Entry

[2]  >>>  Entry.objects
[2]      :  <django.db.models.manager.Manager  object  at  0x7eca70>



                                                                       16
Custom managers

class  EntryManager(models.Manager):
        def  future(self):
                …
        def  past(self):
                …

class  Entry(models.Model):
        …

        objects  =  EntryManager()




                                       17
[1]  >>>  from  yabl.entries.models  import  Entry

[2]  >>>  Entry.objects.future()
[2]      :  [<Entry:  Hi>]

[3]  >>>  Entry.objects.past()
[3]      :  [<Entry:  Man  bites  dog>,  <Entry:  Dog  bites  man>]




                                                                      18
Documentation
 http://django.me/managers




                             19
QuerySets



            20
Filters

[1]  >>>  Author.objects.filter(first_name='Jacob')
[1]      :  [<Author:  Jacob  Kaplan-­‐Moss>]

[2]  >>>  Author.objects.filter(last_name__contains='s')
[2]      :  [<Author:  Miguel  de  Cervantes>,  <Author:  Jacob  Kaplan-­‐Moss>]

[3]  >>>  Author.objects.filter(last_name__contains='s',  first_name='Miguel')
[3]      :  [<Author:  Miguel  de  Cervantes>]

[4]  >>>  Author.objects.filter(last_name__contains='s').filter(first_name='Miguel')
[4]      :  [<Author:  Miguel  de  Cervantes>]




                                                                                       21
Field lookups
exact,  iexact                  name__exact='Joe'
contains,  icontains            name__icontains='s'

startswith,  endswith,  
                                name__endswith='nd'
istartswith,  iendswith

                                name__in=('Joe',  'Jane')
in
                                author__in=Author.objects.filter(…)

gt,  gte,  lt,  lte             cost__gt=100

                                cost__range=(100,  500)
range
                                date__range=(now,  tomrrow)

                                date__year=2009
year,  month,  day,  week_day
                                date__month=7

isnull                          author__isnull=True
regex,  iregex                  name__regex='^J.*b$'

                                                                      22
Following relationships


[1]  >>>  Entry.objects.filter(author__first_name__startswith='J')
[1]      :  [<Entry:  Hi>]

[2]  >>>  Author.objects.filter(entries__headline='Hi')
[2]      :  [<Author:  Jacob  Kaplan-­‐Moss>]


                                 Where’d that come from?

                                                                     23
related_name


class  Entry(models.Model):
        author  =  models.ForeignKey(Author,  related_name='entries')




                                                                        24
select_related()
[1]  >>>  e  =  Entry.objects.get(pk=1)

[2]  >>>  e.author
[2]      :  <Author:  Jacob  Kaplan-­‐Moss>

Oops,  that  did  a  second,  needless  query.

[3]  >>>  e  =  Entry.objects.select_related().get(pk=1)

[4]  >>>  e.author
[5]      :  <Author:  Jacob  Kaplan-­‐Moss>

No  second  query  needed  for  e.author


                                                           25
Limiting select_related()


[1]  >>>  Entry.objects.select_related('author',  'category')

[2]  >>>  Entry.objects.select_related(depth=2)




                                                                26
QuerySet details



                   27
QuerySets are chainable


[1]  >>>  Entry.objects.filter(
    ....:          headline__contains='bites',
    ....:  ).exclude(
    ....:          pub_date__year=2008
    ....:  ).filter(
    ....:          pub_date__month=9
    ....:  )




                                                 28
QuerySets are unique


[1]  >>>  qs1  =  Entry.objects.filter(headline__icontains='dog')

[2]  >>>  qs2  =  qs1.exclude(pub_date__year=2008)

[3]  >>>  qs3  =  qs1.filter(pub_date__year=2008)




                                                                    29
QuerySets are lazy

[1]  >>>  qs  =  Entry.objects.filter(headline__icontains='dog')

[2]  >>>  qs  =  qs.exclude(pub_date__year=2008)

[3]  >>>  qs  =  qs.filter(author__first_name='Jacob')

[4]  >>>  qs
[4]      :  [<Entry:  Man  bites  dog>,  <Entry:  Dog  bites  man>]




                                                                      30
When QuerySets are evaluated


• Iteration   for  i  in  qs


• Slicing     qs[0:5]


• Printing    print  qs,  str(qs)


• len()       len(qs)


• list()      list(qs)




                                    31
Chainable methods
filter(),  exclude()       qs.filter(name='Joe')

order_by()                 qs.order_by('-­‐first_name')

reverse()                  qs.reverse()

distinct()                 qs.distinct()

values(),  values_list()   qs.values('first_name',  'last_name')

                           qs.dates('pub_date',  'year')
dates()
                           qs.dates('pub_date',  'month')

select_related()           qs.select_related()

                           qs.defer('body')
defer(),  only()
                           qs.only('body',  'headline')

                           qs.all()
none(),  all()
                           qs.none()

                                                                   32
Other QuerySet methods
get()             e  =  Entry.objects.get(…)


create()          e  =  Entry.objects.create(…)


get_or_create()   e,  created  =  Entry.objects.get_or_create(…)


count()           Entry.objects.count()


in_bulk()         Entry.objects.in_bulk([1,  2,  3])



latest()          Entry.objects.latest('pub_date')



                                                                   33
Raw SQL


[1]  >>>  query  =  "SELECT  *  FROM  authors_author  WHERE  first_name  =  %s"

[2]  >>>  params  =  ["Jacob"]

[3]  >>>  Entry.objects.raw(query,  params)
[3]          [<Person:  Jacob  Kaplan-­‐Moss>]




                                                                                  34
Entry.objects.raw(query  %  params)




        No!                           35
Other topics



               36
Aggregation
http://jacobian.org/r/django-aggregation




                                           37
Transaction control
 http://jacobian.org/r/django-transactions




                                             38
Exercise:
 /entries/future/
  /entries/past/




                    39
What else?
• Forms, model forms, form sets, ...
• File storage - local and remote.
• Cookies, sessions, authn/authz.
• GeoDjango
• Built-in SQLi, XSS and CSRF protection.
• i18n and l10n support.
• Generic views,
• &c!


                                            1
Thank you!
 jacob@jacobian.org


http://lanyrd.com/sfypm




                          2

More Related Content

PDF
Django Heresies
Simon Willison
 
PDF
The Best (and Worst) of Django
Jacob Kaplan-Moss
 
PDF
Django in the Real World
Jacob Kaplan-Moss
 
PDF
Django a whirlwind tour
Brad Montgomery
 
KEY
Jumpstart Django
ryates
 
PDF
Django - 次の一歩 gumiStudy#3
makoto tsuyuki
 
PDF
Building a Dynamic Website Using Django
Nathan Eror
 
PPTX
Django Architecture Introduction
Haiqi Chen
 
Django Heresies
Simon Willison
 
The Best (and Worst) of Django
Jacob Kaplan-Moss
 
Django in the Real World
Jacob Kaplan-Moss
 
Django a whirlwind tour
Brad Montgomery
 
Jumpstart Django
ryates
 
Django - 次の一歩 gumiStudy#3
makoto tsuyuki
 
Building a Dynamic Website Using Django
Nathan Eror
 
Django Architecture Introduction
Haiqi Chen
 

What's hot (20)

ODP
Getting started with Django 1.8
rajkumar2011
 
PDF
The effective use of Django ORM
Yaroslav Muravskyi
 
PDF
Django Performance Recipes
Jon Atkinson
 
PDF
High Performance Django
DjangoCon2008
 
PDF
OSCON Google App Engine Codelab - July 2010
ikailan
 
PDF
Advanced Django
Simon Willison
 
PDF
Moving from Django Apps to Services
Craig Kerstiens
 
PPTX
The Django Web Application Framework 2
fishwarter
 
PDF
Django Rest Framework and React and Redux, Oh My!
Eric Palakovich Carr
 
PDF
Introducing Assetic: Asset Management for PHP 5.3
Kris Wallsmith
 
PPTX
Maintainable JavaScript 2012
Nicholas Zakas
 
PPT
Django
Kangjin Jun
 
PPTX
Let's write secure drupal code! - Drupal Camp Pannonia 2019
Balázs Tatár
 
PDF
Assetic (Symfony Live Paris)
Kris Wallsmith
 
PPT
Ant
Manav Prasad
 
PPTX
Let's write secure Drupal code! DUG Belgium - 08/08/2019
Balázs Tatár
 
PDF
Assetic (Zendcon)
Kris Wallsmith
 
PPT
Ant
sundar22in
 
PPT
WordPress and Ajax
Ronald Huereca
 
PPT
Intro to-ant
Manav Prasad
 
Getting started with Django 1.8
rajkumar2011
 
The effective use of Django ORM
Yaroslav Muravskyi
 
Django Performance Recipes
Jon Atkinson
 
High Performance Django
DjangoCon2008
 
OSCON Google App Engine Codelab - July 2010
ikailan
 
Advanced Django
Simon Willison
 
Moving from Django Apps to Services
Craig Kerstiens
 
The Django Web Application Framework 2
fishwarter
 
Django Rest Framework and React and Redux, Oh My!
Eric Palakovich Carr
 
Introducing Assetic: Asset Management for PHP 5.3
Kris Wallsmith
 
Maintainable JavaScript 2012
Nicholas Zakas
 
Django
Kangjin Jun
 
Let's write secure drupal code! - Drupal Camp Pannonia 2019
Balázs Tatár
 
Assetic (Symfony Live Paris)
Kris Wallsmith
 
Let's write secure Drupal code! DUG Belgium - 08/08/2019
Balázs Tatár
 
Assetic (Zendcon)
Kris Wallsmith
 
WordPress and Ajax
Ronald Huereca
 
Intro to-ant
Manav Prasad
 
Ad

Viewers also liked (10)

PDF
A quick python_tour
cghtkh
 
PDF
Outside-In Development With Cucumber
Ben Mabey
 
KEY
Capybara
Mona Soni
 
KEY
Make It Cooler: Using Decentralized Version Control
indiver
 
PPTX
Prepare for JDK 9
haochenglee
 
PPT
Introduction to Git for developers
Dmitry Guyvoronsky
 
PDF
Two scoops of Django - Security Best Practices
Spin Lai
 
PDF
The WHY behind TDD/BDD and the HOW with RSpec
Ben Mabey
 
PDF
Jenkins CI
haochenglee
 
PDF
Git Branching Model
Lemi Orhan Ergin
 
A quick python_tour
cghtkh
 
Outside-In Development With Cucumber
Ben Mabey
 
Capybara
Mona Soni
 
Make It Cooler: Using Decentralized Version Control
indiver
 
Prepare for JDK 9
haochenglee
 
Introduction to Git for developers
Dmitry Guyvoronsky
 
Two scoops of Django - Security Best Practices
Spin Lai
 
The WHY behind TDD/BDD and the HOW with RSpec
Ben Mabey
 
Jenkins CI
haochenglee
 
Git Branching Model
Lemi Orhan Ergin
 
Ad

Similar to Introduction To Django (Strange Loop 2011) (20)

PDF
Mini Curso de Django
Felipe Queiroz
 
PDF
The Django Book chapter 5 Models
Vincent Chien
 
PDF
Introduction to Django
Jagdeep Singh Malhi
 
PDF
Django tutorial 2009
Ferenc Szalai
 
PDF
GDG Addis - An Introduction to Django and App Engine
Yared Ayalew
 
KEY
Introduction to Django
James Casey
 
PPT
DJango
Sunil OS
 
PDF
Introduction to Django
Joaquim Rocha
 
PDF
django
webuploader
 
PDF
Django for mobile applications
Hassan Abid
 
PPTX
Django web framework
Abdenour Bouateli
 
PDF
Zagreb workshop
Lynn Root
 
PDF
Gae Meets Django
fool2nd
 
KEY
Introduction Django
Wade Austin
 
PPT
Mini Curso Django Ii Congresso Academico Ces
Leonardo Fernandes
 
PDF
Django tricks (2)
Carlos Hernando
 
PDF
Behind the curtain - How Django handles a request
Daniel Hepper
 
PDF
Google App Engine in 40 minutes (the absolute essentials)
Python Ireland
 
PDF
Тестирование и Django
MoscowDjango
 
PPTX
Hands on django part 1
MicroPyramid .
 
Mini Curso de Django
Felipe Queiroz
 
The Django Book chapter 5 Models
Vincent Chien
 
Introduction to Django
Jagdeep Singh Malhi
 
Django tutorial 2009
Ferenc Szalai
 
GDG Addis - An Introduction to Django and App Engine
Yared Ayalew
 
Introduction to Django
James Casey
 
DJango
Sunil OS
 
Introduction to Django
Joaquim Rocha
 
django
webuploader
 
Django for mobile applications
Hassan Abid
 
Django web framework
Abdenour Bouateli
 
Zagreb workshop
Lynn Root
 
Gae Meets Django
fool2nd
 
Introduction Django
Wade Austin
 
Mini Curso Django Ii Congresso Academico Ces
Leonardo Fernandes
 
Django tricks (2)
Carlos Hernando
 
Behind the curtain - How Django handles a request
Daniel Hepper
 
Google App Engine in 40 minutes (the absolute essentials)
Python Ireland
 
Тестирование и Django
MoscowDjango
 
Hands on django part 1
MicroPyramid .
 

More from Jacob Kaplan-Moss (10)

PDF
Writing great documentation - CodeConf 2011
Jacob Kaplan-Moss
 
KEY
What's new in Django 1.2?
Jacob Kaplan-Moss
 
PDF
Django Introduction, Dev in Rio 2009
Jacob Kaplan-Moss
 
PDF
Snakes on the Web
Jacob Kaplan-Moss
 
KEY
Django In The Real World
Jacob Kaplan-Moss
 
PDF
Building a web framework: Django's design decisions
Jacob Kaplan-Moss
 
PDF
State Of Django
Jacob Kaplan-Moss
 
PDF
Django - the first five years
Jacob Kaplan-Moss
 
PDF
A brief history of Django model syntax
Jacob Kaplan-Moss
 
PDF
Django Update (OSCON 2007)
Jacob Kaplan-Moss
 
Writing great documentation - CodeConf 2011
Jacob Kaplan-Moss
 
What's new in Django 1.2?
Jacob Kaplan-Moss
 
Django Introduction, Dev in Rio 2009
Jacob Kaplan-Moss
 
Snakes on the Web
Jacob Kaplan-Moss
 
Django In The Real World
Jacob Kaplan-Moss
 
Building a web framework: Django's design decisions
Jacob Kaplan-Moss
 
State Of Django
Jacob Kaplan-Moss
 
Django - the first five years
Jacob Kaplan-Moss
 
A brief history of Django model syntax
Jacob Kaplan-Moss
 
Django Update (OSCON 2007)
Jacob Kaplan-Moss
 

Recently uploaded (20)

PDF
AI Unleashed - Shaping the Future -Starting Today - AIOUG Yatra 2025 - For Co...
Sandesh Rao
 
PDF
Advances in Ultra High Voltage (UHV) Transmission and Distribution Systems.pdf
Nabajyoti Banik
 
PPTX
Stamford - Community User Group Leaders_ Agentblazer Status, AI Sustainabilit...
Amol Dixit
 
PDF
Orbitly Pitch Deck|A Mission-Driven Platform for Side Project Collaboration (...
zz41354899
 
PPTX
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
Francisco Vieira Júnior
 
PDF
Security features in Dell, HP, and Lenovo PC systems: A research-based compar...
Principled Technologies
 
PPTX
How to Build a Scalable Micro-Investing Platform in 2025 - A Founder’s Guide ...
Third Rock Techkno
 
PDF
Software Development Company | KodekX
KodekX
 
PDF
BLW VOCATIONAL TRAINING SUMMER INTERNSHIP REPORT
codernjn73
 
PDF
Oracle AI Vector Search- Getting Started and what's new in 2025- AIOUG Yatra ...
Sandesh Rao
 
PDF
Event Presentation Google Cloud Next Extended 2025
minhtrietgect
 
PPTX
The-Ethical-Hackers-Imperative-Safeguarding-the-Digital-Frontier.pptx
sujalchauhan1305
 
PDF
Chapter 2 Digital Image Fundamentals.pdf
Getnet Tigabie Askale -(GM)
 
PDF
SparkLabs Primer on Artificial Intelligence 2025
SparkLabs Group
 
PDF
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
 
PDF
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
PDF
DevOps & Developer Experience Summer BBQ
AUGNYC
 
PDF
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
PDF
The Evolution of KM Roles (Presented at Knowledge Summit Dublin 2025)
Enterprise Knowledge
 
PDF
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
AI Unleashed - Shaping the Future -Starting Today - AIOUG Yatra 2025 - For Co...
Sandesh Rao
 
Advances in Ultra High Voltage (UHV) Transmission and Distribution Systems.pdf
Nabajyoti Banik
 
Stamford - Community User Group Leaders_ Agentblazer Status, AI Sustainabilit...
Amol Dixit
 
Orbitly Pitch Deck|A Mission-Driven Platform for Side Project Collaboration (...
zz41354899
 
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
Francisco Vieira Júnior
 
Security features in Dell, HP, and Lenovo PC systems: A research-based compar...
Principled Technologies
 
How to Build a Scalable Micro-Investing Platform in 2025 - A Founder’s Guide ...
Third Rock Techkno
 
Software Development Company | KodekX
KodekX
 
BLW VOCATIONAL TRAINING SUMMER INTERNSHIP REPORT
codernjn73
 
Oracle AI Vector Search- Getting Started and what's new in 2025- AIOUG Yatra ...
Sandesh Rao
 
Event Presentation Google Cloud Next Extended 2025
minhtrietgect
 
The-Ethical-Hackers-Imperative-Safeguarding-the-Digital-Frontier.pptx
sujalchauhan1305
 
Chapter 2 Digital Image Fundamentals.pdf
Getnet Tigabie Askale -(GM)
 
SparkLabs Primer on Artificial Intelligence 2025
SparkLabs Group
 
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
 
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
DevOps & Developer Experience Summer BBQ
AUGNYC
 
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
The Evolution of KM Roles (Presented at Knowledge Summit Dublin 2025)
Enterprise Knowledge
 
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 

Introduction To Django (Strange Loop 2011)

  • 1. Introduction to Django Jacob Kaplan-Moss Strange Loop 2011 http://lanyrd.com/sfypm
  • 2. Django Training Part 1: Introduction to Django.
  • 3. “Django is a high-level Python web framework that encourages rapid development and clean, ” pragmatic design. 2
  • 4. “Django is a high-level Python web framework that encourages rapid development and clean, ” pragmatic design. 3
  • 5. “Django is a high-level Python web framework that encourages rapid development and clean, ” pragmatic design. 4
  • 6. “Django is a high-level Python web framework that encourages rapid development and clean, ” pragmatic design. 5
  • 7. Documentation http://django.me/design http://www.djangobook.com/en/2.0/chapter01/ 6
  • 8. Which Django version should I use? 7
  • 9. Installing Django • Download and run http://bit.ly/dsetup (http://python-­‐distribute.org/distribute_setup.py) • easy_install  Django • Later: learn about pip and virtualenv http://pip.rtfd.org/ http://virtualenv.rtfd.org/ 8
  • 12. yabl/ __init__.py manage.py settings.py urls.py 11
  • 13. $  python  manage.py  runserver Validating  models... 0  errors  found. Django  version  1.1  beta  1  SVN-­‐10844,  using  settings  'yabl.settings' Development  server  is  running  at  http://127.0.0.1:8000/ Quit  the  server  with  CONTROL-­‐C. 12
  • 14. 13
  • 15. Project settings • DATABASE_ENGINE • DATABASE_NAME • DATABASE_USER • DATABASE_PASSWORD • DATABASE_HOST 14
  • 16. $  python  manage.py  syncdb Creating  table  auth_permission Creating  table  auth_group Creating  table  auth_user Creating  table  auth_message Creating  table  django_content_type Creating  table  django_session Creating  table  django_site You  just  installed  Django's  auth  system,   which  means  you  don't  have  any  superusers  defined. Would  you  like  to  create  one  now?  (yes/no):  yes Username  (Leave  blank  to  use  'jacob'):  jacob E-­‐mail  address:  [email protected] Password:   Password  (again):   Superuser  created  successfully. Installing  index  for  auth.Permission  model Installing  index  for  auth.Message  model 15
  • 17. Documentation http://django.me/about-settings http://django.me/settings http://django.me/manage.py 16
  • 18. Exercise: “it worked!” 17
  • 19. Django Training Part 2: Apps, models, and the admin
  • 24. CREATE  TABLE  "entries_entry"  (        "id"  integer  NOT  NULL  PRIMARY  KEY,        "author_id"  integer  NOT  NULL,        "pub_date"  datetime  NOT  NULL,        "headline"  varchar(200)  NOT  NULL,        "slug"  varchar(50)  NOT  NULL  UNIQUE,        "summary"  text  NOT  NULL,        "body"  text  NOT  NULL ) 6
  • 25. Scary Quirky Language • SQL is tough • SQL knows no version control • DRY • Python is fun! 7
  • 26. import  datetime from  django.db  import  models from  yabl.authors.models  import  Author class  Entry(models.Model):        author              =  models.ForeignKey(Author,  related_name='entries')        pub_date          =  models.DateTimeField(default=datetime.datetime.now)        headline          =  models.CharField(max_length=200)        slug                  =  models.SlugField(unique=True)        summary            =  models.TextField()        body                  =  models.TextField() 8
  • 28. $  python  manage.py  startapp  authors 10
  • 29. authors/ __init__.py models.py tests.py views.py 11
  • 30. INSTALLED_APPS  =  (        "django.contrib.auth",        "django.contrib.contenttypes",        "django.contrib.sessions",          "django.contrib.sites",        "yabl.authors", ) 12
  • 31. from  django.db  import  models class  Author(models.Model):        first_name    =  models.CharField(max_length=200)        last_name      =  models.CharField(max_length=200)        bio                  =  models.TextField(blank=True) 13
  • 32. $  python  manage.py  validate 0  errors  found. 14
  • 33. $  python  manage.py  sqlall  authors BEGIN; CREATE  TABLE  "authors_author"  (        "id"  integer  NOT  NULL  PRIMARY  KEY,        "first_name"  varchar(200)  NOT  NULL,        "last_name"  varchar(200)  NOT  NULL,        "bio"  text  NOT  NULL ); COMMIT; 15
  • 34. $  python  manage.py  syncdb Creating  table  authors_author Installing  index  for  authors.Author  model 16
  • 35. $  python  manage.py  shell [1]  >>>  from  yabl.authors.models  import  Author [2]  >>>  a  =  Author(first_name="John",  last_name="Barth") [3]  >>>  a.save() 17
  • 36. [4]  >>>  Author.objects.all() [4]      :  [<Author:  Author  object>] [5]  >>>  Author.objects.create(first_name='Miguel',  last_name='de  Cervantes') [5]      :  <Author:  Author  object> [6]  >>>  Author.objects.all() [6]      :  [<Author:  Author  object>,  <Author:  Author  object>] [7]  >>>  al  =  Author.objects.filter(first_name='John') [8]  >>>  al[0].last_name [8]      :  u'Barth' [9]  >>>  Author.objects.get(last_name__startswith='de').first_name [9]      :  u'Miguel' 18
  • 38. class  Author(models.Model):        first_name    =  models.CharField(max_length=200)        last_name      =  models.CharField(max_length=200)        bio                  =  models.TextField(blank=True)                def  __unicode__(self):                return  '%s  %s'  %  (self.first_name,  self.last_name) 20
  • 39. class  Author(models.Model):        …        class  Meta:                verbose_name_plural  =  'authors'                ordering  =  ['last_name',  'first_name'] 21
  • 40. [1]  >>>  from  yabl.authors.models  import  Author [2]  >>>  Author.objects.all() [2]      :  [<Author:  John  Barth>,  <Author:  Miguel  de  Cervantes>] [3]  >>>  Author.objects.order_by('-­‐first_name') [3]      :  [<Author:  Miguel  de  Cervantes>,  <Author:  John  Barth>] 22
  • 41. Documentation http://django.me/models http://www.djangobook.com/en/2.0/chapter05/ 23
  • 42. Exercise: Write some apps and some models: • Author (authors app) • Entry (entries app) • first_name (CharField) • author (ForeignKey) • last_name (CharField) • pub_date (DateTimeField) • bio (TextField) • is_published (BooleanField) • headline (CharField) • slug (SlugField) • summary (TextField) • body (TextField) 24
  • 44. “ A Web-based interface, limited to trusted site administrators, that enables the adding, editing and ” deletion of site content. — The Django Book http://djangobook.com/en/2.0/chapter06/ 26
  • 45. from  django.contrib  import  admin from  yabl.authors.models  import  Author admin.site.register(Author) 27
  • 46. INSTALLED_APPS  =  (        'django.contrib.auth',        'django.contrib.contenttypes',        'django.contrib.sessions',        'django.contrib.sites',        'django.contrib.admin',        'yabl.authors',        'yabl.entries', ) 28
  • 47. $  python  manage.py  syncdb Creating  table  django_admin_log Installing  index  for  admin.LogEntry  model 29
  • 48. from  django.conf.urls.defaults  import  * #  Uncomment  the  next  two  lines  to  enable  the  admin: from  django.contrib  import  admin admin.autodiscover() urlpatterns  =  patterns('',        #  Example:        #  (r'^yabl/',  include('yabl.foo.urls')),        #  Uncomment  the  admin/doc  line  below  and  add  'django.contrib.admindocs'          #  to  INSTALLED_APPS  to  enable  admin  documentation:        #  (r'^admin/doc/',  include('django.contrib.admindocs.urls')),        #  Uncomment  the  next  line  to  enable  the  admin:        (r'^admin/',  include(admin.site.urls)), ) 30
  • 49. 31
  • 50. 32
  • 51. 33
  • 52. 34
  • 53. from  django.contrib  import  admin from  yabl.authors.models  import  Author class  AuthorAdmin(admin.ModelAdmin):        pass admin.site.register(Author,  AuthorAdmin) 35
  • 54. Documentation http://djangobook.com/en/2.0/chapter06/ http://django.me/admin 36
  • 55. Exercise: 37
  • 56. Django Training Part 3: URLs, views, and templates
  • 57. Views 2
  • 59. 4
  • 60. URLs 5
  • 61. page.php script.cgi?pageid=144 StoryPage.aspx 6
  • 65. yabl/urls.py from  django.conf.urls.defaults  import  * #  Uncomment  the  next  two  lines  to  enable  the  admin: from  django.contrib  import  admin admin.autodiscover() urlpatterns  =  patterns('',        (r'^authors/$',                  'yabl.authors.views.author_list'),        (r'^authors/(d+)/$',      'yabl.authors.views.author_detail'),        (r'^admin/',  include(admin.site.urls)), ) 10
  • 66. yabl/authors/urls.py from  django.conf.urls.defaults  import  * urlpatterns  =  patterns('',        (r'^$',                  'yabl.authors.views.author_list'),        (r'^(d+)/$',      'yabl.authors.views.author_detail'), ) 11
  • 67. yabl/urls.py from  django.conf.urls.defaults  import  * #  Uncomment  the  next  two  lines  to  enable  the  admin: from  django.contrib  import  admin admin.autodiscover() urlpatterns  =  patterns('',        (r'^authors/',  include('yabl.authors.urls')),        (r'^admin/',      include(admin.site.urls)), ) 12
  • 68. Regex crash course a The letter “a”. a+ One or more “a”s. b? Zero or one “b”s. c{1,3} One, two, or three “c”s. . Any single character. [abc] Either an “a”, “b”, or “c”. [A-­‐Z] Any character between “A” and “Z”. [A-­‐Za-­‐z0-­‐9]? Zero or one letters “A-Z”, “a-z”, or “0-9”. (d{3,4}) A group containing three or four digits. (w*) A group containing zero or more word characters (letters/digits). [^/]+ One or more characters until (and not including) a forward slash. ^(joe|bob) A string starting with “joe” or “bob”. (?P<id>d+) A group named “id” containing one or more digits. article/$ A string ending with “article/” 13
  • 69. Dissecting a request • GET  /authors/1/ • ROOT_URLCONF • yabl.urls • (r'^authors/',  include('yabl.authors.urls')) • yabl.authors.urls • (r'^$',  'author_list')                    (no match) • (r'^(d+)/',  'author_detail')      (match!) • author_detail(request,  '1') 14
  • 72. yabl/authors/views.py from  django.http  import  HttpResponse def  author_list(request):        return  HttpResponse("This  is  the  author  list!") 17
  • 73. yabl/authors/views.py from  django.http  import  HttpResponse from  yabl.authors.models  import  Author def  author_list(request):        r  =  "<ul>"        for  a  in  Author.objects.all():                r  +=  "<li>%s</li>"  %  a.name        r  +=  "</ul>"        return  HttpResponse(r) 18
  • 74. yabl/authors/views.py from  django  import  template from  django.http  import  HttpResponse from  yabl.authors.models  import  Author def  author_list(request):        as  =  Author.objects.all()        tmpl  =  template.loader.get_template("authors/index.html")        context  =  template.Context({"authors":  as})        return  HttpResponse(tmpl.render(context)) 19
  • 75. yabl/authors/views.py from  django.shortcuts  import  render from  yabl.authors.models  import  Author def  author_list(request):        context  =  {"authors"  :  Author.objects.all()}        return  render(request,  "authors/index.html",  context) 20
  • 76. yabl/authors/views.py from  django.http  import  Http404 from  django.shortcuts  import  render_to_response from  yabl.authors.models  import  Author def  author_detail(request,  author_id):        try:                author  =  Author.objects.get(id=author_id)        except  Author.DoesNotExist:                raise  Http404()        return  render(request,  "authors/detail.html",  {"author"  :  author}) 21
  • 77. yabl/authors/views.py from  django.shortcuts  import  render_to_response,  get_object_or_404 from  yabl.authors.models  import  Author def  author_detail(request,  author_id):        author  =  get_object_or_404(Author,  id=author_id)        return  render(request,  "authors/detail.html",  {"author"  :  author}) 22
  • 78. Templates 23
  • 80. <!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN"> <html  lang="en"> <head><title>Authors</title></head> <body> <h1>Authors  ({{  authors|length  }}  total)</h1> <ul> {%  for  a  in  authors  %} <li> <a  href="{{  a.id  }}/">{{  a.name  }}</a> </li> {%  endfor  %} </ul> </body> </html> 25
  • 81. Where to templates go? • In an app’s templates directory. • In directories specified by settings.TEMPLATE_DIRS. • ... 26
  • 82. TEMPLATE_DIRS  =  [        '/path/to/some/templates/',        '/path/to/some/more/other/templates/', ] 27
  • 83. TEMPLATE_DIRS  =  [        '/Users/jacob/Projects/stl-­‐django/yabl/templates/', ] 28
  • 84. <!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN"> <html  lang="en"> <head><title>Authors</title></head> <body> <h1>Authors  ({{  authors|length  }}  total)</h1> <ul> {%  for  a  in  authors  %} <li> <a  href="{{  a.id  }}/">{{  a.name  }}</a> </li> {%  endfor  %} </ul> </body> </html> 29
  • 85. The magic dot • a["name"] • a.name • a.name() 30
  • 86. <!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN"> <html  lang="en"> <head><title>Authors</title></head> <body> <h1>Authors  ({{  authors|length  }}  total)</h1> <ul> {%  for  a  in  authors  %} <li> <a  href="{{  a.id  }}/">{{  a.name  }}</a> </li> {%  endfor  %} </ul> </body> </html> 31
  • 89. <!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN"> <html  lang="en"> <head><title>Authors</title></head> <body> <h1>Authors  ({{  authors|length  }}  total)</h1> <ul> {%  for  a  in  authors  %} <li> <a  href="{{  a.id  }}/">{{  a.name  }}</a> </li> {%  endfor  %} </ul> </body> </html> 34
  • 91. <!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN"> <html  lang="en"> <head> <title> {%  block  title  %}YABL{%  endblock  %} </title> </head> <body> <div  id="content"> {%  block  content  %}{%  endblock  %} </div> <div  id="footer"> {%  block  footer  %}Copyright  blah..{%  endblock  %} </div> </body> </html> 36
  • 92. <!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN"> <html  lang="en"> <head> <title> {%  block  title  %}YABL{%  endblock  %} </title> </head> <body> <div  id="content"> {%  block  content  %}{%  endblock  %} </div> <div  id="footer"> {%  block  footer  %}Copyright  blah..{%  endblock  %} </div> </body> </html> 37
  • 93. {%  extends  "base.html"  %} {%  block  title  %} Authors  |  {{  block.super  }} {%  endblock  %} {%  block  content  %} <h1>Authors  ({{  authors|length  }}  total)</h1> <ul> {%  for  a  in  authors  %} <li> <a  href="{{  a.id  }}/">{{  a.name  }}</a> </li> {%  endfor  %} </ul> {%  endblock  %} 38
  • 94. ! " 93&45; !"#$%&$'()#*+,)$-.$'$/0123&45*#"6 !"#$%&$'()#*+,)$23&45*#"6 93$,(; ##9&0&5$; !"#+5718#&0&5$#"6 ##!!#)$1&07'2&0&5$#66 $ !"#+5718#&0&5$#"6 ##ABC7/5(2174 ####!"#+5718#&0&5$#"6!"#$'(+5718#"6 ##9<&0&5$; !"#$'(+5718#"6 !"#$'(+5718#"6 9<3$,(; 9+7(>; !"#+5718#17'&$'&#"6 !"#+5718#/,05#"6 ##9(0G#0(H*/,05*; ##93:;!!#)$1&07'2&0&5$#669<3:; ##9D5; ####!"#+5718#/,05#"6!"#$'(+5718#"6 ##!"#=7/#)&7/>#0'#)&7/>-50)&#"6 ####950;E74$9<50; ##9<(0G; ####93?;!!#)&7/>23$,(50'$#669<3?; ####950;A71,5#'$F)9<50; ##9(0G#0(H*17'&$'&*; ####9@;!!#)&7/>2&$,)$#66 ####222 ####!"#+5718#17'&$'&#"6!"#$'(+5718#"6 ##!"#$'(=7/#"6 ##9<D5; ##9<(0G; !"#$'(+5718#"6 !"#$'(+5718#"6 9<+7(>; section_index.html base_generic.html 9<3&45; base.html # 39
  • 95. Why? 40
  • 96. Inheritance tips • {% extends %} must be the first thing in your template. • More {% block %}s are better. • If you’re duplicating content, you’re missing a block. • {{ block.super }} 41
  • 97. Documentation http://djangobook.com/en/2.0/chapter04/ http://django.me/templates 42
  • 98. Exercise: /authors/ /authors/{id}/ /entries/ /entries/{slug}/ 43
  • 104. Model instances a.k.a. “row” 6
  • 106. Models 8
  • 107. Instance methods class  Entry(models.Model):        …        def  is_by_jacob(self):                return  "jacob"  in  self.author.name.lower() … [1]  >>>  e  =  Entry.objects.get(pk=1) [2]  >>>  e.is_by_jacob() [2]      :  False 9
  • 109. __unicode__ class  Entry(models.Model):        …        def  __unicode__(self):                return  self.headline … [1]  >>>  Entry.objects.all() [1]      :  [<Entry:  Man  bites  dog>,  <Entry:  Dog  bites  man>] 11
  • 110. save class  Entry(models.Model):        …        def  save(self,  **kwargs):                self.word_count  =  count_words(self.body)                super(Entry,  self).save(**kwargs) 12
  • 111. save class  Entry(models.Model):        …        def  save(self,  **kwargs):                self.word_count  =  count_words(self.body)                super(Entry,  self).save(**kwargs) Don’t forget this part! 13
  • 112. delete class  Author(models.Model):        …        def  delete(self):                nobody  =  Author.objects.get(first_name='<NOBODY>')                self.entries.update(author=nobody)                super(Author,  self).delete() 14
  • 113. Managers 15
  • 114. Default manager class  Entry(models.Model):        …        objects  =  models.Manager() … [1]  >>>  from  yabl.entries.models  import  Entry [2]  >>>  Entry.objects [2]      :  <django.db.models.manager.Manager  object  at  0x7eca70> 16
  • 115. Custom managers class  EntryManager(models.Manager):        def  future(self):                …        def  past(self):                … class  Entry(models.Model):        …        objects  =  EntryManager() 17
  • 116. [1]  >>>  from  yabl.entries.models  import  Entry [2]  >>>  Entry.objects.future() [2]      :  [<Entry:  Hi>] [3]  >>>  Entry.objects.past() [3]      :  [<Entry:  Man  bites  dog>,  <Entry:  Dog  bites  man>] 18
  • 118. QuerySets 20
  • 119. Filters [1]  >>>  Author.objects.filter(first_name='Jacob') [1]      :  [<Author:  Jacob  Kaplan-­‐Moss>] [2]  >>>  Author.objects.filter(last_name__contains='s') [2]      :  [<Author:  Miguel  de  Cervantes>,  <Author:  Jacob  Kaplan-­‐Moss>] [3]  >>>  Author.objects.filter(last_name__contains='s',  first_name='Miguel') [3]      :  [<Author:  Miguel  de  Cervantes>] [4]  >>>  Author.objects.filter(last_name__contains='s').filter(first_name='Miguel') [4]      :  [<Author:  Miguel  de  Cervantes>] 21
  • 120. Field lookups exact,  iexact name__exact='Joe' contains,  icontains name__icontains='s' startswith,  endswith,   name__endswith='nd' istartswith,  iendswith name__in=('Joe',  'Jane') in author__in=Author.objects.filter(…) gt,  gte,  lt,  lte cost__gt=100 cost__range=(100,  500) range date__range=(now,  tomrrow) date__year=2009 year,  month,  day,  week_day date__month=7 isnull author__isnull=True regex,  iregex name__regex='^J.*b$' 22
  • 121. Following relationships [1]  >>>  Entry.objects.filter(author__first_name__startswith='J') [1]      :  [<Entry:  Hi>] [2]  >>>  Author.objects.filter(entries__headline='Hi') [2]      :  [<Author:  Jacob  Kaplan-­‐Moss>] Where’d that come from? 23
  • 122. related_name class  Entry(models.Model):        author  =  models.ForeignKey(Author,  related_name='entries') 24
  • 123. select_related() [1]  >>>  e  =  Entry.objects.get(pk=1) [2]  >>>  e.author [2]      :  <Author:  Jacob  Kaplan-­‐Moss> Oops,  that  did  a  second,  needless  query. [3]  >>>  e  =  Entry.objects.select_related().get(pk=1) [4]  >>>  e.author [5]      :  <Author:  Jacob  Kaplan-­‐Moss> No  second  query  needed  for  e.author 25
  • 124. Limiting select_related() [1]  >>>  Entry.objects.select_related('author',  'category') [2]  >>>  Entry.objects.select_related(depth=2) 26
  • 126. QuerySets are chainable [1]  >>>  Entry.objects.filter(    ....:          headline__contains='bites',    ....:  ).exclude(    ....:          pub_date__year=2008    ....:  ).filter(    ....:          pub_date__month=9    ....:  ) 28
  • 127. QuerySets are unique [1]  >>>  qs1  =  Entry.objects.filter(headline__icontains='dog') [2]  >>>  qs2  =  qs1.exclude(pub_date__year=2008) [3]  >>>  qs3  =  qs1.filter(pub_date__year=2008) 29
  • 128. QuerySets are lazy [1]  >>>  qs  =  Entry.objects.filter(headline__icontains='dog') [2]  >>>  qs  =  qs.exclude(pub_date__year=2008) [3]  >>>  qs  =  qs.filter(author__first_name='Jacob') [4]  >>>  qs [4]      :  [<Entry:  Man  bites  dog>,  <Entry:  Dog  bites  man>] 30
  • 129. When QuerySets are evaluated • Iteration for  i  in  qs • Slicing qs[0:5] • Printing print  qs,  str(qs) • len() len(qs) • list() list(qs) 31
  • 130. Chainable methods filter(),  exclude() qs.filter(name='Joe') order_by() qs.order_by('-­‐first_name') reverse() qs.reverse() distinct() qs.distinct() values(),  values_list() qs.values('first_name',  'last_name') qs.dates('pub_date',  'year') dates() qs.dates('pub_date',  'month') select_related() qs.select_related() qs.defer('body') defer(),  only() qs.only('body',  'headline') qs.all() none(),  all() qs.none() 32
  • 131. Other QuerySet methods get() e  =  Entry.objects.get(…) create() e  =  Entry.objects.create(…) get_or_create() e,  created  =  Entry.objects.get_or_create(…) count() Entry.objects.count() in_bulk() Entry.objects.in_bulk([1,  2,  3]) latest() Entry.objects.latest('pub_date') 33
  • 132. Raw SQL [1]  >>>  query  =  "SELECT  *  FROM  authors_author  WHERE  first_name  =  %s" [2]  >>>  params  =  ["Jacob"] [3]  >>>  Entry.objects.raw(query,  params) [3]          [<Person:  Jacob  Kaplan-­‐Moss>] 34
  • 137. Exercise: /entries/future/ /entries/past/ 39
  • 138. What else? • Forms, model forms, form sets, ... • File storage - local and remote. • Cookies, sessions, authn/authz. • GeoDjango • Built-in SQLi, XSS and CSRF protection. • i18n and l10n support. • Generic views, • &c! 1