$30 off During Our Annual Pro Sale. View Details »

Hunting For Treasure In Django

Seb
May 28, 2015

Hunting For Treasure In Django

Seb

May 28, 2015
Tweet

More Decks by Seb

Other Decks in Technology

Transcript

  1. Hunting for Treasure
    in Django
    Sebastian Vetter
    @elbaschid

    View Slide

  2. Who Am I?

    View Slide

  3. Sebastian
    • Django & Python Developer
    • Backend Engineer @ Mobify
    • github/twitter: elbaschid

    View Slide

  4. What's The Treasure?

    View Slide

  5. Awesome Django Features
    • Forms,
    • Views,
    • Models,
    • the ORM, or
    • other commonly used APIs.

    View Slide

  6. But They Are Boring

    View Slide

  7. Real Treasure

    View Slide

  8. What Does That Mean?
    • Useful pieces of Django code.
    • Considered public API.
    • Documentation is available (sort of).
    • Mainly used within Django itself.

    View Slide

  9. My Hunting Strategy
    • Digging through the Django source.
    • Hanging out with Funkybob.
    • Learning from other great people.

    View Slide

  10. What I'll Do
    • Show a few "hidden" treasures.
    • Explain what they do.
    • Look at examples.

    View Slide

  11. cached_property

    View Slide

  12. Where is it useful?
    • Time or compute heavy properties on a class.
    • Synchronous calls to remote servers.
    • Used more than once, e.g. code & template.

    View Slide

  13. What does it do?
    • It's a decorator.
    • Caches the return value.
    • Lives as long as the instance.

    View Slide

  14. It looks like this
    class MyObject(object):
    @cached_property
    def compute_heavy_method(self):
    ...
    return result

    View Slide

  15. Imagine A Color API
    class Color(object):
    def __init__(self, hex):
    self.hex = hex
    def _request_colour_name(self, hex):
    print "Requesting #{}".format(hex)
    rsp = requests.get(API_ENDPOINT.format(hex))
    return rsp.json()[0].get("title")
    @property
    def name(self):
    return self._request_colour_name(self.hex)

    View Slide

  16. Here's the problem
    • Using the name attribute will call the API
    • Every time!

    View Slide

  17. Here's the problem
    >>> c = Color('ffffff')
    >>> c.name
    Requesting #ffffff
    white
    >>> c.name
    Requesting #ffffff
    white

    View Slide

  18. Possible solution
    @property
    def name(self):
    if self._name is None:
    self._name = self._request_colour_name(self.hex)
    return self._name

    View Slide

  19. Or you can use cached_property
    from django.utils.functional import cached_property
    @cached_property
    def name(self):
    return self._request_colour_name(self.hex)

    View Slide

  20. Using the cached property
    >>> c = Color('ffffff')
    >>> c.name
    Requesting #ffffff
    white
    >>> c.name
    white

    View Slide

  21. Isn't That Great

    View Slide

  22. All you Need To Know
    from django.utils.functional import cached_property
    • Only cached for the lifetime of the instance.
    • Be careful with querysets.
    • Django docs
    • Source

    View Slide

  23. import_string

    View Slide

  24. Where is it useful?
    • Make a class or function configurable.
    • Allow loading class/function from string.

    View Slide

  25. What does it do?
    • Takes dotted path to a class or function.
    • Loads it.
    • Returns the class or function object.

    View Slide

  26. It looks like this
    from django.utils.module_loading import import_string
    get_func = import_string('requests.get')
    print get_func
    #
    get_func('https://google.ca')
    #

    View Slide

  27. # settings.py
    UPLOAD_VALIDATION_PIPELINE = [
    'my_project.uploads.validators.is_tarball',
    'my_project.uploads.validators.has_readme_file',
    'my_project.uploads.validators.has_no_!']

    View Slide

  28. All you Need To Know
    from django.utils.module_loading import import_string
    • Imports a class or function from a dotted path.
    • Django docs
    • Source

    View Slide

  29. lazy and
    lazy_property

    View Slide

  30. Where is it useful?
    • Accessing settings at parse time, e.g. class attributes.
    • Translating strings outside of a view.
    • Translations in the settings module.

    View Slide

  31. Here's a problem
    class UserSignupView(CreateView):
    ...
    success_url = reverse('signup-confirmed')

    View Slide

  32. How can we fix it?
    from django.utils.functional import lazy
    class UserSignupView(CreateView):
    ...
    success_url = lazy(reverse('signup-confirmed'), unicode)

    View Slide

  33. Lazy Django
    • The Settings object is lazy.
    • Several helpers have lazy siblings:
    • reverse_lazy
    • ugettext_lazy
    • Not sure what lazy_property is useful for.

    View Slide

  34. All you Need To Know
    from django.utils.functional import lazy
    from django.utils.functional import SimpleLazyObject
    • Imports a class or function from a dotted path.
    • Django docs
    • Source

    View Slide

  35. RequestFactory

    View Slide

  36. Where Is It Useful?
    • Testing request related code.
    • Mocking will be too much work.
    • Using the test client doesn't make sense.

    View Slide

  37. Create GET Request
    from django.test import RequestFactory
    request = RequestFactory().get('/some/path')
    # with a query string
    query_params = {"token": "secret-token"}
    request = RequestFactory().get('/some/path', data=query_params)

    View Slide

  38. Create POST Request
    from django.test import RequestFactory
    post_params = {'username':'testuser', 'password':'supersecret'}
    request = RequestFactory().post('/login', data=post_params)

    View Slide

  39. All you Need To Know
    from django.test import RequestFactory
    • Creates a fake request for given URL.
    • Can handle all HTTP methods.
    • Will save you some mocking work.
    • Django docs
    • Source

    View Slide

  40. The Treasure Is Yours

    View Slide

  41. Thanks! Questions?
    • www.roadsi.de
    • @elbaschid
    • github.com/elbaschid
    Slides: https://speakerdeck.com/elbaschid

    View Slide