10 Packages for Your Next Django Project

Last week I attended DjangoCon Europe 2019 in the beautiful city of Copenhagen. The organizers did a great job putting together a fantastic event with three days of insightful talks covering a wide variety of topics followed by two days of sprints. I had a great time catching up with old friends and meeting new ones.

Also, I had the opportunity to give a breakout session titled “Behind the Curtain – How Django handles a Request” where I took a room full of Djangonauts on a deep dive through the bits of Django that are touched by every HTTP request, but rarely by any human.

If you missed out on all that fun, don’t despair, recordings of the talks are online.

Now, it’s easy to return from a conference with a warm fuzzy feeling, but without any actionable takeaways. To counter that, I compiled a smorgasbord of some great Python packages, modules, and classes that I learned about at DjangoCon Europe this year.

📦 IPython.display.JSON – Displays an interactive JSON widget in Jupyter Notebook.

Mentioned in Jupyter, Django, and Altair – Quick and dirty business analytics by Chris Adams

When I want to hash out a piece of code, I regularly use Jupyter Notebook for that. IPython.display.JSON displays a JSON object as an interactive widget, which comes in handy when working with large JSON objects. It takes a dict or list, but it can also read directly from a file or URL. The IPython.display module contains more goodies of that kind. You can easily use Jupyter Notebook with Django with the shell_plus command from django-extensions.

📦 requests-respectful – A wrapper around requests to work within rate limits.

Mentioned in Fetching data from APIs (GitHub) using Django and GraphQl without hitting the rate limits by Manaswini Das

When working with external APIs, you usually have to honor some kind of rate limit. That sounds simple but becomes quite complicated once multiple threads, processes or machines are involved. requests-respectful solves this by using Redis to keep track of your API usage.

from requests_respectful import RespectfulRequester

rr = RespectfulRequester()

# This can be done elsewhere but the realm needs to be registered!
rr.register_realm("Github", max_requests=100, timespan=60)

response = rr.get("http://github.com", params={"foo": "bar"}, realms=["Github"], wait=True)

📦 structlog – A library to make logging both less painful and more powerful.

Mentioned in Logging Rethought 2: The Actions of Frank Taylor Jr. by Markus Holtermann

Python’s logging module can be challenging to wrap your head around. structlog aims to simplify it. Instead of just logging a message, it allows you to easily add key/value pairs that carry more information about an event.

>>> import structlog
>>> log = structlog.get_logger()
>>> log.msg("greeted", whom="world", more_than_a_string=[1, 2, 3])  
2016-09-17 10:13.45 greeted                        more_than_a_string=[1, 2, 3] whom='world'

📦 django-stubs – Type stubs and a mypy plugin for Django.

Mentioned in Lightning Talk Type-checking your Django by Seth Yastrov

I think optional static typing is a great compromise between the rigidness of a statically typed language and the potential maintenance issues of dynamic typing. mypy is a powerful tool in the Python developers toolbox, but the highly dynamic nature of Django limits its usefulness. django-stubs improves the type checks mypy can do. Also check out djangorestframework-stubs.

📦 OSMGeoAdmin – An GeoDjango admin class for geometries that uses Open Street Map.

Mentioned in Maps with GeoDjango, PostGIS and Leaflet by Paolo Melchiorre

GeoDjango has special admin classes to view and edit geometries. This particular one uses Open Street Map for visualization. This one might not be big news for anyone familiar with GeoDjango, but I just recently started using and somehow
completely missed this part of the docs.

📦 django-money – Money fields for django forms and models.

Mentioned in Building a custom model field from the ground up by Dmitry Dygalo

I got 99 problems but money ain’t one. At least storing monetary values in a Django application isn’t a problem anymore, thanks to the MoneyField from django-money. It not only stores the amount correctly but also the currency and knows how to display it correctly. django-money packs a ton of other features, like validation, currency conversion, and Django REST framework support.

📦 bellybutton – A customizable, easy-to-configure linting engine for Python.

Mentioned in Maintaning a Django codebase after 10k commits by Joachim Jablon and St├ęphane “Twidi” Angel

If you are looking for a way to lint your code that goes beyond pylint and flake8, bellybutton might be for you. It allows you to write custom rules using astpath, an XPath-like syntax for querying Python ASTs.

📦 django-classy-settings – A Class-based way to manage Django settings.

Mentioned in Lightning Talk Another View on Handling Settings by Curtis Maloney

For any non-trivial Django project, you almost always end up with slightly different settings for different environments. There are various solutions for this, for example, having multiple settings files starting with a from base_settings import * statement. django-classy-settings solves this problem using a class-based approach.

📦 confucius – An easy way to provide environ backed config in your projects.

Mentioned in Lightning Talk Another View on Handling Settings by Curtis Maloney

This package is a fresh take on environment-specific settings. It also uses classes but comes with the additional twist that it can read settings from environment variables and uses type annotation to automatically convert them to the right type. With a __getattr__ at the module level, a new feature in Python 3.7 (see PEP 562), you can write a pretty neat settings file:

from confucius import BaseConfig

class Config(BaseConfig):
    DB_HOST = 'localhost'
    DB_PORT = 5432

__getattr__ = Config.module_getattr_factory()

📦 django-context-decorator – A decorator to build the context of a class based view.

Mentioned on Twitter by Tobias Kunze

Instead of overwriting the get_context_data in your class-based view, just add this decorator to any attributes or methods of your class and they will be added automagically. This one wasn’t mentioned at the conference, but it was created during the sprints (and I read about it on Twitter while I procrastinated on this article), so I think it belongs here.

from django_context_decorator import context
from django.utils.functional import cached_property
from django.views.generic import TemplateView

class MyView(TemplateView):
    template_name = 'path/to/template.html'

    def context_variable(self):
        return 'context value'

    def context_property(self):
        return 'context property'

    def expensive_context_property(self):
        return 'expensive context property'

There you have it, 10 packages that will save you hours of development time. Obviously, this is only a small sample of all the packages and tools that were mentioned at DjangoCon Europe 2019. If you were there, your list might look very different. If you need a good argument to convince your boss (or yourself) why attending a conference like DjangoCon is worth it, just point them to this page.

Header photo by Nick Karvounis, Code examples from the documentation of the respective packages.

Leave a Reply