1
class Control(models.Model):
    period = models.DurationField()
    active = models.BooleanField()
    device_collection = models.ForeignKey(DeviceSet)

class DeviceSet(models.Model):
    name = models.CharField()
    date_last_control = models.DateField()

    def get_next_control(self):
        return self.date_last_control + self.control_actif.period

    @property
    def control_actif(self):
        if not hasattr(self, "_control"):
            setattr(self, "_control", self.control_set.get(active=True))
        return self._control

There are several Control associated with DeviceSet but only one Control which is active by DeviceSet. I'd like to get the active Control of the DeviceSet when I get the queryset in a column _control. I already try :

DeviceSet.objects.annotate(_control = Q(control__active=True))

That don't work

'WhereNode' object has no attribute 'output_field'

And after set output_field=Control I have the following exception:

type object 'Control' has no attribute 'resolve_expression'

I just want to have like a prefetch_related with filter but in a new column to use the _control attribute in model's method.

Quentin
  • 144
  • 8

1 Answers1

1

You are getting errors from what you've attempted because annotate method needs an aggregate function (eg Sum, Count etc) rather than a Q object.

Since Django 1.7 it's possible to do what you want using prefetch_related, see docs here: https://docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.Prefetch

DeviceSet.objects.prefetch_related(
    Prefetch('control_set',
             queryset=Control.objects.filter(active=True),
             to_attr='_control')
)
Anentropic
  • 32,188
  • 12
  • 99
  • 147