Can a model manager access its models' Meta attribute (`Meta.unique_together`)?

django, django-models, metaclass, natural-key

Solution

In order to get the actual options passed to meta, you should use `self.model._meta` rather than `self.model.Meta`

Problem

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) ```

Original source