views:

935

answers:

1

I'm writing a mixin which will allow my Models to be easily translated into a deep dict of values (kind of like .values(), but traversing relationships). The cleanest place to do the definitions of these seems to be in the models themselves, a la:

class Person(models.Model, DeepValues):
    name = models.CharField(blank=True, max_length=100)
    tribe = models.ForeignKey('Tribes')

    class Meta:
        schema = {
            'name' : str,
            'tribe' : {
                'name' : str
            }
        }

Person.objects.all().deep_values() => {
    'name' : 'Andrey Fedorov',
    'tribe' : {
        'name' : 'Mohicans'
    }
}

However, Django complains about my including this in class Meta with:

TypeError: 'class Meta' got invalid attribute(s): schema

(entire stack trace here)

Now, I suppose I could elaborately override this in my mixin, but is there a more elegant way of storing this information?

+6  A: 

I don't know about elegant, but one pragmatic way is:

import django.db.models.options as options

options.DEFAULT_NAMES = options.DEFAULT_NAMES + ('schema',)

Obviously, this would break if Django ever added a 'schema' attribute of its own. But hey, it's a thought...you could always pick an attribute name which is less likely to clash.

Vinay Sajip
Perfect! Merci beaucoup!
Andrey Fedorov
For posterity's sake, that doesn't work, but this did: options.DEFAULT_NAMES = options.DEFAULT_NAMES + ('default_values',)
Andrey Fedorov
Oh... it's presumably because my solution converts DEFAULT_NAMES to a list, whereas your refinement keeps it as a tuple.
Vinay Sajip
Most likely! :)
Andrey Fedorov