Porting Django Apps to Python3


By Kamil Gałuszka S4F Team
           
7.11.2013 PySilesia

Joke Starter


class _UnexpectedSuccess(Exception):
    pass

try: ... # Some great logic here. ...except _UnexpectedSuccess: print("This works ! :) ")




Why Django 1.6? 


  • True Python 3 support ( YAY! ) !
  • Persistent database connection ! ( You used PgBouncer right? )
  • GeoDjango form widgets ( no need of 3rd party floppyforms )
  • Sessions are now JSON serializable 



PS. This release is dedicated to Malcolm Tredinnick. His work won't be forgotten by Django community.

Sad part...
:-(



Work by Andrew Godwin (Pull Request #376)
sponsored by crowdfunding on Kickstarter with 

django.db.migrations
will land in Django 1.7.

We have to wait more...

Python 3 

Start with this... (by Lennart Regebro. Yeah it's free)

There are six awesome tools ;)


from six import with_metaclass

class Meta(type):
    pass

class Base(object):
    pass

class MyClass(with_metaclass(Meta, Base)):
    pass

# Conditionals if needed (last resort)
if six.PY2:     print("YAY! I'm very old python 2")

if six.PY3:     print("I'm new sexy Python 3.3 !")

Fact #1
Unicode is the King


from __future__ import unicode_literals

u'This is bad although it will work on python 3.3'
'This is much better'
b'This is when you explicitly need byte strings'


Question #0. Do you write tests?






Offtopic #Unicode 7.0 did you known...


Fact #1 Unicode is the King

django.utils.encoding
from django.utils.encoding import *      # using asterix is BAD idea ;]
# old utils for strings and unicodesmart_strsmart_unicodeforce_unicode
# new utils for stringssmart_bytessmart_textsmart_text

Fact #1
Unicode is the King. Be kind and use decorators.

from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible
class AbstractBaseUser(models.Model):
    username = models.CharField(_('username'), max_length=128)
    password = models.CharField(_('password'), max_length=128)    last_login = models.DateTimeField(_('last login'), default=timezone.now)

    is_active = True

    REQUIRED_FIELDS = []    def __str__(self): # we rename only __unicode__ to __str__         return self.username

Fact #2
Iterator is your new  friend 


def _iterkeys(self):    for k, v in self._iteritems():
        yield k

def _itervalues(self):
    for k, v in self._iteritems():
        yield v

if six.PY3:
    items = _iteritems
    keys = _iterkeys
    values = _itervalues
else:
    iteritems = _iteritems
    iterkeys = _iterkeys
    itervalues = _itervalues

Fact #3 Tox can be your friend


[tox]
envlist = py2.7-d1.6, py3.3-d1.6

[testenv] commands = py.test tests/ deps = mock pytest-django [testenv:py2.7-d1.6] basepython = python2.7 deps = django>=1.6,<1.7 [testenv:py3.3-d1.6] basepython = python3.3 deps = django>=1.6,<1.7

Fact #4 Rewrite Exceptions

# PYTHON 3
try:
    ...
except MyException as exc:
    ...

# Python 2 try: ... except MyException, exc: # Don't do that! ...

Are there JavaScript geeks here?



Meet.JS in Katowice

JavaScript community together (yay!)

THANK 

YOU ALL!!!!

Any questions?

Porting Django Apps to Python3

By Kamil Gałuszka

Porting Django Apps to Python3

  • 2,003
Loading comments...

More from Kamil Gałuszka