ModelMixin

the problem

Each application needs to enrich models of other application with methods that should live on the “foreign” application. As an example, suppose to have application jmb.fax that need to define get_fax_description on the the Organization instances to properly display fax information in its completion widget.

Since jmb.organization may well live w/o jmb.fax (does not depend on it) it’s a mistake to add that method to Organization unless jmb.fax is declared in the INSTALLED_APPS.

the solution

Each application can create a file called mixins that holds all mixins that want foreign application to provide. Let’s continue with the previous example. jmb.fax will provide jmb.fax.mixins:

class OrganizationOrganizationMixin(object):
    def get_fax_description(self):
        return "%s [%s]" % (
            self.name, self.fax
        )

and jmb.organization.models will define Organization models as:

from jmb.core import db

OrganizationMixin = db.get_mixin('OrganizationOrganizationMixin')
class Organization (DateModel, UserModel, StatusModel, OrderedModel, OrganizationMixin):
   ...

Clearly this is based on the name convention that mixins area called in an univocal way. We choose to use app_label, model_name, Mixin as in OrganizationOrganizationMixin.

The mixin module is read when models are written, it’s important to prevent any circular dependency. It’s probably a good idea to make all imports within methods. No check is done that method names don’t clash eash other, that’s up to the programmer

The result is:

In [1]: from jmb.organization import models
In [2]: thu = models.Organization.objects.get(name='Thunder Systems Srl')
In [3]: t1.get_fax_description()
Out[3]: u'Thunder Systems Srl -  [02.58018012]'

API

jmb.core.db.get_mixin(name)[source]

Return a Mixin that collect all Mixins for a specific Model. It tries to import it from all INSTALLED_APPS in module app.mixin. An empty Mixin is returned if no app provides anything

Parameters

name – the name of the Mixin that must be looked for in all apps

Returns

a mixin