Here is my attempt at a generic manager of the natural key model. It's like docs , except that it tries (unsuccessfully) to determine the field names of the natural key from the Meta.unique_together attribute.
class NaturalKeyModelManager(Manager):
def get_by_natural_key(self, *args):
field_dict = {}
for i, k in enumerate(self.model.Meta.unique_together[0]):
field_dict[k] = args[i]
return self.get(**field_dict)
If I insert debug printing just before the for loop, as follows:
print dir(self.model.Meta)
it does not list the unqiue_together attribute:
['__doc__', '__module__', 'abstract']
The “abstract” bit bothered me, but another debugging fingerprint shows that the model I'm trying to manipulate natural keys with is not abstract:
>>> print self.model.Meta.abstract
False
I mix a lot of abstract base classes. Could this be a problem?
class MixedModel(NamedModel, TimeStampedModel, VersionedModel, Model):
objects = NaturalKeyModelManager()
class Meta:
unique_together = (('name', 'version',),)
For completeness, here is one of the mixins:
class TimeStampedModel(Model):
created = DateTimeField(_("Created"), auto_now_add=True, null=True, editable=False)
updated = DateTimeField(_("Updated"), auto_now=True, null=True, editable=True)
class Meta:
abstract = True
The hard-coded model manager works very well:
class MixedModelManager(Manager):
def get_by_natural_key(self, name, version):
return self.get(name=name, version=version)