Recently, when working with Django, I wanted to create a class that would automatically render instances of a model as an editable HTML table. I used a Django-esque approach to defining the table columns, such that it was similar to Model and Form classes:
class ProductTable(Table): _model = Product name = TextWidget() description = TextWidget() size = DropDownWidget()
The underscore in _model is there to prevent a name collision with the column names, but it’s a bit ugly. If I was strictly following the Django approach, I probably would have added an inner class:
class ProductTable(Table): class Meta: _model = Product name = TextWidget() description = TextWidget() size = DropDownWidget()
But that’s a lot of extra noise. What I really wanted was something more like template classes in C++.
template <class Model> class Table : public TableBase { // ... } class ProductTable : public Table<Product> { // ... }
If Python supported class decorators, I could have just put @model(Product) before the class definition. The approach I chose is to inherit from a class dynamically generated by a function that takes the parameter I need, so my ProductTable class now becomes:
class ProductTable(Table(Product)): name = TextWidget() description = TextWidget() size = DropDownWidget()
Much nicer! Now it pretty much reads as ‘a ProductTable is a kind of Table (a Product one)’, which makes sense. To support this, I have a Table function that looks like this:
def Table(model): class TableDynamicBase(TableBase): _model = model return TableDynamicBase
TableBase contains whatever was in the original Table base class (which in my case was some unrelated metaclass magic).