user5892612
user5892612

Reputation:

Django models Manager isn't accessible via model instances

I get this error 'Manager isn't accessible via Stage instances'. I have spent few good hours trying to work it out but I have got no clue what I am doing wrong.

models.py

class StageManager(models.Manager):
    def get_queryset(self):
        return super(StageManager, self).get_queryset().filter(stage=self.id, stage__zone=self.zone).aggregate(Sum('substage_value'))


class Stage(models.Model):
    tablerow_stage = models.ForeignKey(TRStage)
    stage_value = models.PositiveSmallIntegerField(default=0)
    slug = models.SlugField(unique=True)
    zone = models.ForeignKey(Zone)

    objects = models.Manager() # The default manager
    subs_objects = StageManager()

    def __str__(self):
        return '%s.%s.%s' % (self.zone.project,
                             self.tablerow_stage.stage_num,
                             self.zone.zone_num)

line of code from template:

<td style="width:40px" align="center">{{ stage.subs_objects }}</td>

Upvotes: 0

Views: 1546

Answers (1)

Anonymous
Anonymous

Reputation: 12090

Django does not allow you to do stage.objects, only Stage.objects (only via class, not instance of the class). Your custom queryset follows the same rule. But thing is, even if this was allowed, you queryset would not work - you are referencing fields such as id and zone that only exist in model instances, not managers.

Now I'm not entirely sure what you are actually trying to achieve, but here's a method you can stick in the Stage class instead of having that queryset.

def substage_sum(self):
    return self.__class__.objects.filter(
        stage=self.id, 
        stage__zone=self.zone
    ).aggregate(
        sum=Sum('substage_value')
    ).values_list('sum', flat=True).first()

This would return a single value that represents the sum, assuming that's what you want.

Upvotes: 2

Related Questions