Here's my attempt at a generalized natural key model manager. It's like the docs except it tries (unsuccessfully) to determine the natural key field names 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 a debug print just before the for loop like this:
print dir(self.model.Meta)
it doesn't list the unqiue_together attribute at all:
['__doc__', '__module__', 'abstract']
The 'abstract' bit worried me, but another debug print shows that the model I'm trying manage with natural keys is not abstract:
>>> print self.model.Meta.abstract
False
I am mixing in a lot of abstract base classes. Could that be the problem?
class MixedModel(NamedModel, TimeStampedModel, VersionedModel, Model):
    objects = NaturalKeyModelManager()
    class Meta:
        unique_together = (('name', 'version',),)
For completeness here's 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 just fine:
class MixedModelManager(Manager):
    def get_by_natural_key(self, name, version):
        return self.get(name=name, version=version)
In order to get the actual options passed to meta, you should use self.model._meta rather than self.model.Meta
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With