To Object or Not to Object?

English is Confusing

English can be a confusing language. When I say "object" I mean a Python object and not to object to something. Of course, the reader may object to the content of this article, but that is beside the point.

But I digress.

Defining Options

When building extensible applications in Python, we often have to answer the question of how best to allow a developer to customize the functionality.

Consider this hypothetical example for defining options for a list view:

class ListOptions(object):

    def __init__(search_enabled=False, search_fields=None, search_minimum_length=3):
        # ...

There are numerous parameters beginning with search_. One solution might be to pass a dictionary instead.

search_params = {
    'search_enabled': True,
    'search_fields': ("title", "description"),
    'search_minimum_length': 3,
}
options = ListOptions(**search_params)

This is perhaps better, but it's still sort of messy.

Using Objects as Configuration

Another way would be to define a search class:

class Search(object):

    def __init__(*fields, enabled=True, length=3):
        # ...


options = ListOptions(search=Search("title", "description"))

While this approach proliferates the number of classes, it is much cleaner and also easier for a developer to use. Code completion provides information and the style is expressive and closer to natural language.

Additionally, using classes and their instances for configuration provides a kind of data structure that makes the whole system more extensible.

These are the principles upon which SuperDjango UI hangs its development practices.

# projects/ui.py
from superdjango import ui
from .models import Project

class ProjectUI(ui.ModelUI):
    model = Project

    list_options = ui.ListOptions(
        "title",
        "owner",
        "start_dt",
        "end_dt",
        "priority",
        filtering=ui.Filtering("priority", "owner"),
        ordering=ui.Ordering("start_dt", "end_dt", "priority")
    )

The example above supplies two configuration instances to ListOptions to indicate how the list may be filtered and ordered.



Posted in Extensibility by Shawn Davis, April 15, 2020