1
\$\begingroup\$

I'm writing a custom Manager for my django app that lets you group django-enumfields:

class NWODCharacter(models.Model):

    class Meta:
        abstract = True

    attributes = GenericRelation('CharacterAttributeLink')

    @property
    def physical_attributes(self):
        return [self.attributes.filter(attribute=attribute) for attribute
                in AttributeAbility.objects.physical()]
    # And 8 others

To get to the attributes we need these two:

class CrossCharacterMixin(models.Model):
    cross_character_types = models.Q(app_label='mage', model='mage')
    content_type = models.ForeignKey(ContentType, limit_choices_to=cross_character_types,
                                     null=True, blank=True)
    object_id = models.PositiveIntegerField(null=True)
    content_object = GenericForeignKey('content_type', 'object_id')

    class Meta:
        abstract = True

class CharacterAttributeLink(Trait, CrossCharacterMixin):
    attribute = models.ForeignKey('AttributeAbility')

And now AttributeAbility and the CategoryManager:

class AttributeAbility(models.Model):

    class Attributes(AutoNumber):
        INTELLIGENCE = ()  # Mental, Power
        WITS = ()  # Mental', 'Finesse
        RESOLVE = ()  # Mental', 'Resistance
        STRENGTH = ()  # Physical', 'Power
        DEXTERITY = ()  # Physical', 'Finesse
        STAMINA = ()  # Physical', 'Resistance
        PRESENCE = ()  # Social', 'Power
        MANIPULATION = ()  # Social', 'Finesse
        COMPOSURE = ()  # Social', 'Resistance

    attribute = EnumField(Attributes)
    objects = CategoryManager()

    @property
    def category(self):
        attribute_group = lambda attribute: (
            int((attribute.value - 1) / 3)) + 1 % 3

        return Category(attribute_group(self.attribute))

    class Meta:
        verbose_name_plural = "Attribute Abilities"

    def __str__(self):
        return self.attribute.label

class Category(AutoNumber):
    MENTAL = ()
    PHYSICAL = ()
    SOCIAL = ()


class CategoryManager(models.Manager):

    '''
    Class to manage instances that rely on the category enum
    '''

    def physical(self):
        return [categorised_item for categorised_item in super(CategoryManager, self).get_queryset().all()
                if categorised_item.category == Category['PHYSICAL']]

    def mental(self):
        return [categorised_item for categorised_item in super(CategoryManager, self).get_queryset().all()
                if categorised_item.category == Category['MENTAL']]

    def social(self):
        return [categorised_item for categorised_item in super(CategoryManager, self).get_queryset().all()
                if categorised_item.category == Category['SOCIAL']]

My concern is over the number of queries, and the use of List Comprehension. I'm also wondering if this is a common pattern, or if there is a 'better' practice to achieving this.

1 AutoNumber.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.