Parameterized Django models

Posted by mgibsonbr on Programmers See other posts from Programmers or by mgibsonbr
Published on 2012-05-24T20:31:37Z Indexed on 2012/06/27 21:25 UTC
Read the original article Hit count: 258

In principle, a single Django application can be reused in two or more projects, providing functionality relevent to both. That implies that the same database structure (tables and relations) will be re-created identically in different databases, and most times this is not a problem (assuming the projects/databases are unrelated - for instance when someone downloads a complete app to use in their own projects).

Sometimes, however, the models must be "tweaked" a little to better fit the problem needs. This can be accomplished by forking the app, but I wondered if there wouldn't be a better option in cases where the app designer can anticipate the most common customizations.

For instance, if I have a model that could relate to another as one-to-one or one-to-many, I could specify the unique property as a parameter, that can be specified in the project's settings:

class This(models.Model):
    other = models.ForeignKey(Other, unique=settings.OTHER_TO_THIS)

Or if a model can relate to many others, I could create an intermediate table for each of them (thus enforcing referential integrity) instead of using generic fks:

for related in settings.MODELS_RELATED_TO_OTHER:
    model_name = '%s_Other' % related
    globals()[model_name] = type(model_name, (models.Model,) {
        me:models.ForeignKey(find_model_class(related)),
        other:models.ForeignKey(Other),
        # Some other properties all intersection tables must have
    })

Etc. Let me stress out that I'm not proposing to change the models at runtime nor anything like that; once the parameters were defined and syncdb called for the first time, those parameters are not to be changed again (unless you're doing a schema migration).

Is this a good design? Are there better ways to accomplish the same thing, or maybe drawbacks I coulnd't anticipate? This technique is meant to be used sparingly (only on apps meant to be reused in wildly different contexts, and only when a specific need of customization can be detected while the app model is being designed).

© Programmers or respective owner

Related posts about design-patterns

Related posts about database-design