Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Upgrade to Django 1.8

Upgrade to Django 1.8

Why you might be interested in Django 1.8, and a (very) brief overview of what you will get if you upgrade.

9dafad54b5b4f360b7aae5f482bc1c91?s=128

Tzu-ping Chung

February 27, 2015
Tweet

More Decks by Tzu-ping Chung

Other Decks in Programming

Transcript

  1. Upgrade to Django 1.8

  2. Should I upgrade?

  3. Should I upgrade now?

  4. No.

  5. Django 1.8 Roadmap Jan. 12, 2015 Feature freeze; alpha release.

    Freeze: Jan. 12. Alpha: Jan. 16. Feb. 16 Beta; non-blocking bug freeze. Beta 1: Feb 25. March 16 RC 1; translation freeze. 2+ weeks after RC Final, or another RC if needed. * Data accurate as of 2015-02-25
  6. Django has, historically, never made a release date. — Andrew

    Godwin, PyCon 2014
  7. Why? • Long term support release. • You should migrate

    sooner or later. • Use it for your next project.
  8. Updated URL Patterns Syntax

  9. from  django.conf.urls  import  patterns,  url   from  pages  import  views

      urlpatterns  =  patterns(          '',          url(r'^$',  views.home),          url(r'^$',  views.about),   )
  10. from  django.conf.urls  import  patterns,  url   from  pages  import  views

      urlpatterns  =  patterns(          '',          url(r'^$',  views.home),          url(r'^$',  views.about),   ) Wat
  11. from  django.conf.urls  import  patterns,  url   #  No  need  to

     import.   urlpatterns  =  patterns(          '',          url(r'^$',  'pages.views.home'),          url(r'^$',  'pages.views.about'),   ) Django “Magic”
  12. from  django.conf.urls  import  patterns,  url   urlpatterns  =  patterns(  

           'pages.views',          url(r'^$',  'home'),          url(r'^$',  'about'),   ) More Magic
  13. Nobody write like that anymore.

  14. from  django.conf.urls  import  patterns,  url   from  pages  import  views

      urlpatterns  =  patterns(          '',          url(r'^$',  views.home),          url(r'^$',  views.about),   ) What you should do What you should do
  15. from  django.conf.urls  import  patterns,  url   from  pages  import  views

      urlpatterns  =  patterns(          '',          url(r'^$',  views.Homeview.as_view()),          url(r'^$',  views.AboutView.as_view()),   ) Especially with CBVs
  16. from  django.conf.urls  import  url   from  pages  import  views  

    urlpatterns  =  [          url(r'^$',  views.home),          url(r'^$',  views.about),   ] Django 1.8
  17. URL Patterns • Use a list in new projects •

    You can still use pattern() • Auto-import is deprecated
  18. Data-loading in Tests

  19. class  StoreViewTests(TestCase):          def  setUp(self):    

                 Store.objects.create(                          name='KFC',                          notes="Without  Original  Recipe.  WTF.",                  )                  mcdonalds  =  Store.objects.create(name='McDonalds')                  MenuItem.objects.create(                          store=mcdonalds,  name='Big  Mac',  price=79,                  ) Django < 1.8
  20. class  StoreViewTests(TestCase):          @classmethod      

       def  setUpTestData(cls):                  Store.objects.create(                          name='KFC',                          notes="Without  Original  Recipe.  WTF.",                  )                  mcdonalds  =  Store.objects.create(name='McDonalds')                  MenuItem.objects.create(                          store=mcdonalds,  name='Big  Mac',  price=79,                  ) Django 1.8
  21. Database flushing • DB-level commit/rollback • Class-level data initialisation •

    Fallback to the old behaviour transactions are unavailable
  22. Better behaviour with unsaved foreign keys

  23. >>>  book  =  Book.objects.create(name="Django")   >>>  book.author  =  Author(name="John")  

    >>>  book.author.save()   >>>  book.save()   >>>  Book.objects.get(name="Django")   >>>  book.author   >>> Django < 1.8
  24. id author_id name 1 null Django book  =  Book.objects.create(name="Django")

  25. id author_id name 1 null Django id name null John

    book.author  =  Author(name="John")
  26. id author_id name 1 null Django id name 1 John

    book.author.save() Oops
  27. >>>  book.author  =  Author(name="john")   Traceback  (most  recent  call  last):

      ...   ValueError:  Cannot  assign  "<Author:  John>":   "Author"  instance  isn't  saved  in  the  database. Django 1.8
  28. class  BookForm(forms.ModelForm):          def  save(self,  *args,  **kwargs):

                     book  =  super().save(*args,  **kwargs)                  #  This  fails  in  Django  1.8  if  book.author                  #  is  not  yet  saved.  Get  it  from  the  form                  #  instead:                    #  self.cleaned_data['author'].name                  book.title  =  "%s  by  %s"  %  (                          book.title,  book.author.name                  )                  return  book Gotcha
  29. Good stuffs • UUIDField   • uuid.uuid   • DurationField

      • datetime.timedelta
  30. More • Features from django-secure • django.contrib.postgres • Formalised Model._meta

    API
  31. Better ORM

  32. Why I Hate the Django ORM by Alex Gaynor https://www.youtube.com/watch?v=GxL9MnWlCwo

  33. #  F  expression.   Products.objects.filter(          on_delivery__gt=F('in_stock')

      )             #  Aggregation.   Products.objects.annotate(          count_sum=Sum('in_stock')   )
  34. #  FAIL!!   Products.objects.annotate(          count_sum=Sum(  

                   F('in_stock')  +  F('on_delivery')          )   )   ...   AttributeError:  'ExpressionNode'  object   has  no  attribute  'split()' Django < 1.8
  35. #  Only  this  works.   Products.objects.annotate(        

     count_sum=Sum('in_stock')   )   Django < 1.8
  36. #  Only  this  works.   Products.objects.annotate(        

     count_sum=Sum('in_stock')   )   Django < 1.8 This needs to be a string
  37. #  This  worked  and  will  work.   Products.objects.annotate(    

         count_sum=Sum('in_stock'))             #  This  will  work.   Products.objects.annotate(          count_sum=Sum(F('in_stock')))             #  This  will  become  possible.   Products.objects.annotate(          count_sum=Sum(F('in_stock')  +                                        F('on_delivery'))) Django 1.8
  38. Author.objects.order_by(Length('name').asc())   Author.objects.annotate(          screen_name=Coalesce(    

                 'alias',  'goes_by',  'name'          )   )   Author.objects.annotate(          screen_name=Concat(                  'name',  V('  ('),  'goes_by',  V(')')          )   ) Django 1.8
  39. Multiple Template Engine Support

  40. First-class Jinja2 Support (applause, please)

  41. Before Django 1.8 • django.template • Template to HTML •

    How Django handle templates • Coupled with other parts of Django • Many settings for both components
  42. Django 1.8 • django.template • django.template.backends • One settings: TEMPLATES

  43. #  Don't  use  this  one.   ALLOWED_INCLUDE_ROOTS   TEMPLATE_CONTEXT_PROCESSORS  

    TEMPLATE_DEBUG   TEMPLATE_DIRS   TEMPLATE_LOADERS   TEMPLATE_STRING_IF_INVALID
  44. TEMPLATES  =  [          {    

               'BACKEND':  ('django.template.backends.'                                        'django.DjangoTemplates'),                  'DIRS':  [],                  'APP_DIRS':  True,                  'OPTIONS':  {                          'context_processors':  [                                  #  ...                          ],                  },          },   ]
  45. TEMPLATE_CONTEXT_PROCESSORS (BACKEND)['CONFIG] ['context_processors'] TEMPLATE_DEBUG (BACKEND)['CONFIG]['debug'] TEMPLATE_DIRS (BACKEND)['DIRS'] TEMPLATE_LOADERS (BACKEND)['CONFIG]['loaders'] (BACKEND)['APP_DIRS']

    TEMPLATE_STRING_IF_INVALID (BACKEND)['CONFIG] ['string_if_invalid']
  46. TEMPLATE_CONTEXT_PROCESSORS (BACKEND)['CONFIG] ['context_processors'] TEMPLATE_DEBUG (BACKEND)['CONFIG]['debug'] TEMPLATE_DIRS (BACKEND)['DIRS'] TEMPLATE_LOADERS (BACKEND)['CONFIG]['loaders'] (BACKEND)['APP_DIRS']

    TEMPLATE_STRING_IF_INVALID (BACKEND)['CONFIG] ['string_if_invalid'] All deprecated
  47. Django + Jinja2 Maybe next time. To be continued.

  48. WHAT IF I AM INTERESTED IN SOMETHING ELSE?