-1

How do you query a model for an aggregate of a ForeignKey 'computed' (Autofield?) field

I have two models:

class Job(models.Model):
    name = models.CharField(…)

class LineItem(models.Model):
    job = models.ForeignKey(Job, …)
    metric_1 = models.DecimalField(…)
    metric_2 = models.DecimalField(…)
    metric_3 = models.DecimalField(…)
    # Making this a @property, @cached_property, or the like makes no difference
    def metric_total(self):
        return (self.metric_1 + self.metric_2 * self.metric_3)

In the view:

class StackoverflowView(ListView, …):
    model = Job

    def get_queryset(self):
        return Job.objects
            .select_related(…)
            .prefetch_related('lineitem_set')
            .filter(…).order_by(…)

    def get_context_data(self, **kwargs):
        context_data = super(StackoverflowView, self).get_context_data(**kwargs)
        context_data['qs_aggregate'] = self.get_queryset() \
            .annotate(
                # Do I need to Annotate the model?
            ).aggregate(
                # This works for any of the fields that have a model field type
                metric1Total=Sum('lineitem__metric_1'),
                metric2Total=Sum('lineitem__metric_2'),
                # This will error : 
                # Unsupported lookup 'metric_total' for AutoField or join on the field not permitted.
                # How do I aggregate the computed model field 'metric_total'?
                metricTotal=Sum('lineitem__metric_total'),
            )
        return context_data

When I try to aggregate the computed field, I get the error: Unsupported lookup 'metric_total' for AutoField or join on the field not permitted.. How do I aggregate these special fields?

chris Frisina
  • 19,086
  • 22
  • 87
  • 167

1 Answers1

1

You have to calculate metric_total too

Job.objects.aggregate(
    metric1Total=Sum('lineitem__metric_1'),
    metric2Total=Sum('lineitem__metric_2'),
    metric_total=Sum('lineitem__metric_1') + Sum('lineitem__metric_2')
)

A possible dup: Django @property used in .aggregate()

In short, these annotate() and aggregate() methods are performed on the Database level whereas the metric_total() "method" performs on the Python level.

JPG
  • 82,442
  • 19
  • 127
  • 206