title: Django JSONField filtering Queryset where filter value is annotated sum value
body: <p>How do I properly write the filter code so it returns only the Animals that are not sold out.</p>
  
  <p>I'm using POSTGRES db,  python3.6 and Django 2.1.7 (currently there are v2.2a1,v2.2b1 pre-release versions)</p>
  
  <p>My questioin is an extension to <a href="https://stackoverflow.com/q/36389871/2848256">Django JSONField filtering</a>
  which filters on a hard coded value in the filter. </p>
  
  <p>My Case requires an annotated value in the filter.</p>
  
  <p><code>models.py</code> I know that the models can be optimized, but I already have huge amount of records since  more than 3 years</p>
  
  <pre><code>from django.db import models
  from django.contrib.postgres.fields import JSONField
  
  class Animal(models.Model):
      data = models.JSONField(verbose_name=_('data'), blank=True)
  
  class Sell(models.Model):
      count = models.IntegerField(verbose_name=_('data'), blank=True)
      animal = models.ForeignKey('Animal', 
                                 on_delete=models.CASCADE,
                                 related_name="sales_set",
                                 related_query_name="sold"
     )
  </code></pre>
  
  <p>in my api I want to return only the animals that still have something left for selling </p>
  
  <pre><code>animal = Animal(data={'type':'dog', 'bread':'Husky', 'count':20})
  </code></pre>
  
  <p>What I want to filter should be similar to animal.data['count'] > sum(animal.sales_set__count</p>
  
  <pre><code>Animal.objects.annotate(animals_sold=Sum('sales_set__count'))
  .filter(data__contains=[{'count__gt': F('animals_sold')}])
  </code></pre>
  
  <p>with the code above i get <code>builtins.TypeError
  TypeError: Object of type 'F' is not JSON serializable</code></p>
  
  <p>if I remove the <code>F</code> it won't filter on the value of the animals_sold, but on the text 'animals_sold' and it doesn't do any help.</p>
  
  <pre><code>Animal.objects.annotate(animals_sold=Sum('sales_set__count'))
  .filter(data__contains=[{'count__gt': F('animals_sold')}])
  </code></pre>
  
  <p>Edit 1:
  There is one more topic here that can be linked:
  <a href="https://stackoverflow.com/questions/42675803/postgres-values-query-on-json-key-with-django">Postgres: values query on json key with django</a></p>
  
  <p>Edit 2:
  here is some additional code with custom transform classes as suggested in <a href="https://code.djangoproject.com/ticket/29769#comment:5" rel="nofollow noreferrer">related django ticket</a></p>
  
  <pre><code>from django.db.models.constants import LOOKUP_SEP
  from django.db.models import F, Q, Prefetch, Sum
  from django.db.models import IntegerField, FloatField, ExpressionWrapper
  from django.db.models.functions import Cast
  from django.contrib.postgres.fields import JSONField
  from django.contrib.postgres.fields.jsonb import KeyTransform, KeyTextTransform
  
  class KeyIntegerTransform(KeyTransform):  # similar to KeyTextTransform
      """ trasnform the data.count to integer """
      operator = '-&gt;&gt;'
      nested_operator = '#&gt;&gt;'
      output_field = IntegerField()
  
  class KeyIntTransformFactory:
      """ helper class for the JSONF() """
  
      def __init__(self, key_name):
          self.key_name = key_name
  
      def __call__(self, *args, **kwargs):
          return KeyIntegerTransform(self.key_name, *args, **kwargs)
  
  
  class JSONF(F):
      """ for filtering on JSON Fields """
  
      def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False):
          rhs = super().resolve_expression(query, allow_joins, reuse, summarize, for_save)
          field_list = self.name.split(LOOKUP_SEP)
          for name in field_list[1:]:
              rhs = KeyIntegerTransform(name)(rhs)
          return rhs
  
  
  </code></pre>
  
  <p>queryset filtering I tried so far:</p>
  
  <pre><code>q = q.filter(data__contains={'count__gt':JSONF('sold_count_sum')})
  # err: Object of type 'JSONF' is not JSON serializable
  
  q = q.filter(sold_count_sum__lt=Cast(JSONF('data_count'), IntegerField()))
  # err: operator does not exist: text -&gt;&gt; unknown
  
  q = q.filter(sold_count_sum__lt=Cast(JSONF('data__count'), IntegerField()))
  # err: 'KeyIntegerTransform' takes exactly 1 argument (0 given)
  
  q = q.filter(sold_count_sum__lt=KeyIntegerTransform('count', 'data'))
  # err: operator does not exist: text -&gt;&gt; unknown
  
  q = q.filter(sold_count_sum__lt=F('data__count'))
  # err: operator does not exist: text -&gt;&gt; unknown
  
  q = q.filter(sold_count_sum__lt=F('data_count'))
  # err: operator does not exist: text -&gt;&gt; unknown
  
  q = q.filter(sold_count_sum__lt=JSONF('data_count'))
  # err: operator does not exist: text -&gt;&gt; unknown
  
  q = q.filter(sold_count_sum__lt=JSONF('data__count'))
  # err: 'KeyIntegerTransform' takes exactly 1 argument (0 given)
  
  q = q.filter(sold_count_sum__lt=JSONF('data', 'count'))
  # err: JSONF.__init__() takes 2 params
  
  
  </code></pre>