Design Note: Reconciling “Bare” Python Classes with Django¶
Problem¶
Django’s django.db.models.Model
class must be root class of all persistent
objects. This imposes certain implicit structure rules, and the associated methods
and attribiutes. It also defeats ordinary Python class definition
techniques, specifically limiting inheritance.
See Design Note: Recursive Structures in SQL for the root-cause issue. When we define the Python objects, we can use ordinary containers which are part of a simple inheritance hierarchy to represent the hierarchical message structures in a strongly-typed object structure.
When we switch from Python to Django, however, we loose inheritance, but gain a different kind of strongly typed record definition.
We have to consider how best to define structures that permit us to have arbitrary Python class definitions as well as the more-constrained Django ORM.
Also, see Design Note: Key Generation for X12Messages for the consequent issue of how best to generate keys in the Django implementation so that it doesn’t depend on database saves.
Forces¶
There are a number of alternatives.
Use SQLAlchemy instead of Django’s built-in models. Since the Django views and templates are not tightly bound to the model, this certainly will work. SQLAlchemy mappings can be used to bridge between the original Python classes and the database model, minimizing the impact on existing code. However, Django’s built-in Admin interface won’t work with this external model definition.
Rewrite
X12.parse
to use the Django model. This is relatively small, sinceX12.parse
makes limited references to theX12.message
package. This tends to bind X12 parse to Django persistence even if we’re doing other kinds of X12 message processing.Rewrite
X12.parse
to use the formal Factory design pattern. The Django application model module and theX12.message
modules would all provide the necessary factory function to emit proper objects for use byX12.parse
. Since there are relatively few distinct classes inX12.message
, this Factory is not terribly complex.Assure that the various modules have precisely the same API, eliminating the need for a formal Factory object. Since Django provides the most built-in functionality,
X12.message
modules would have to emulate the Django model API.
Solution¶
Use a formal Factory design pattern for utilities outside the Django application framework.
Consequences¶
Some minor complex with the indirect creation of message objects in X12.parse
.
However, this is the only place where the indirection occurs. All other
modules either use X12.parse
or the Django web app.