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