title: Filtering by annotated field of a related model
body: <p>I am calculating a field on the fly (=not storing in the DB) and need to filter a related model by that field.</p>
  <p>My questions are as follows:</p>
  <ol>
  <li>Any ideas how can I filter over related fields that are calculated?</li>
  <li>I would like to understand how Django handles queries (e.g. whether / if / when it is returning a QuerySet and operating on that or if it's hitting the DB directly). If someone could point out to me the relevant documentation, that would be much appreciated!</li>
  </ol>
  <p><strong>Additional information</strong></p>
  <p>My Models (models.py)</p>
  <pre><code>from .managers import StackManager, PartManager
  class Build(models.Model):
      ...
  
  class Part(models.Model):
      build = models.ForeignKey('Build', models.CASCADE, related_name='parts')
      x_min = models.FloatField()
      x_max = models.FloatField()
      y_min = models.FloatField()
      y_max = models.FloatField()
      z_min = models.FloatField()
      z_max = models.FloatField()
      volume = models.FloatField()
      objects = PartManager()
  
  class Stack(models.Model):
      build = models.OneToOneField('Build', models.DO_NOTHING, related_name='stack')
      height = models.FloatField()
      objects = StackManager()
  </code></pre>
  <p>My Model Managers and QuerySet Managers (managers.py)</p>
  <pre><code>class StackQuerySet(models.QuerySet):
      def calc(self,**kwargs):
          valid_parts = self.filter(
              build__parts__y__lte=F('height'),
              ) \
          .annotate(
              total_built_parts_volume = Sum(F('build__parts__volume'))
          )
          return valid_parts
  
  class StackManager(models.Manager):
      def get_queryset(self):
          return StackQuerySet(self.model, using=self._db)
  
  class PartManager(models.Manager):
      def get_queryset(self):
          return super().get_queryset()\
                  .annotate(
                      x = F('x_max') + F('x_min'),
                      y = F('y_max') + F('y_min'),
                      z = F('z_max') + F('z_min')
                  )
  </code></pre>
  <p>What I am trying to call</p>
  <pre><code>Stack.objects.get_calc()
  </code></pre>
  <ul>
  <li><p>Because the &quot;y_min&quot; and &quot;y_max&quot; could easily change, I want to keep
  the &quot;y&quot; as a computed field. However, I need &quot;y&quot; also in other
  calculations and this doesn't seem to be possible as I am getting</p>
  <blockquote>
  <p>Related Field got invalid lookup: y</p>
  </blockquote>
  </li>
  <li><p>I have already moved the fields from properties (@property in model)
  to a custom Model Manager, but this doesn't seem to help either. It
  seems to me that filter and F() objects are directly hitting the DB
  without returning a QuerySet, but I cannot even confirm this as I
  didn't manage to find relevant documentation.</p>
  </li>
  <li><p>As an additional note, I can't import Models into .managers.py file
  as this will cause a circular reference...</p>
  </li>
  </ul>