#30854: FilteredRelation on ManyToOne generates wrong result
-------------------------------------+-------------------------------------
               Reporter:             |          Owner:  nobody
  mortezaPRK                         |
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  2.2
  layer (models, ORM)                |       Keywords:  FilteredRelation
               Severity:  Normal     |  annotate
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 When using FilteredRelation multiple times in single query, results are
 wrong.
 consider following example (with Django 2.2.6):

 The models are:
 {{{#!python
 from django.db import models


 class UserType(models.Model):
     pass


 class Commodity(models.Model):
     pass


 class CommodityCount(models.Model):
     commodity = models.ForeignKey(Commodity, on_delete=models.CASCADE)
     user_type = models.ForeignKey(UserType, on_delete=models.CASCADE)
     small_box = models.IntegerField(default=0)

     class Meta:
         unique_together = ('commodity', 'user_type')


 class CommodityDiscount(models.Model):
     commodity = models.ForeignKey(Commodity, on_delete=models.CASCADE)
     user_type = models.ForeignKey(UserType, on_delete=models.CASCADE)
     small_box = models.IntegerField(default=0)

     class Meta:
         unique_together = ('commodity', 'user_type')

 }}}

 following query is what I want:

 {{{#!python
 query = Commodity.objects.annotate(
     cnt=FilteredRelation('commoditycount',
 condition=Q(commoditycount__user_type_id=1)),
     dst=FilteredRelation('commoditydiscount',
 condition=Q(commoditydiscount__user_type_id=1))
 ).filter(
     cnt__isnull=False,
     dst__isnull=False
 ).select_related('cnt','dst')
 }}}

 resulting query is ok:

 {{{#!sql
 SELECT
     "ma_commodity"."id",
     cnt."id",
     cnt."commodity_id",
     cnt."user_type_id",
     cnt."small_box",
     dst."id",
     dst."commodity_id",
     dst."user_type_id",
     dst."small_box"
 FROM
     "ma_commodity"
     INNER JOIN "ma_commoditycount" cnt ON (
         "ma_commodity"."id" = cnt."commodity_id"
         AND (cnt."user_type_id" = 1)
     )
     INNER JOIN "ma_commoditydiscount" dst ON (
         "ma_commodity"."id" = dst."commodity_id"
         AND (dst."user_type_id" = 1)
     )
 WHERE
     (
         cnt."id" IS NOT NULL
         AND dst."id" IS NOT NULL
     )
 }}}

 but results are not ok:


 {{{#!python
 first_item = query.first()
 print(dir(first_item))
 >>> [ ... '_state', 'check', 'clean', 'clean_fields',
 'commoditycount_set', 'commoditydiscount_set',
     'date_error_message', 'delete', 'dst', 'from_db', 'full_clean',
 'get_deferred_fields', 'id', 'objects',
     'pk', 'prepare_database_save', 'refresh_from_db', 'save', 'save_base',
 'serializable_value', 'unique_error_message', 'validate_unique'
     ]
 }}}

 as you can see, there is dst, but no cnt.
 if I remove dst and its related FilteredRelation, cnt re appear.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30854>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/053.4c78270743dc9c935d5d3cebf1f9d202%40djangoproject.com.

Reply via email to