It sounds like you understand what the current behaviour is, and you think 
that it would be better modelled with Q objects, is that the case? I can 
see where you're coming from, as even the docs explain the difference 
loosely in terms of AND and OR.

Q(entry__headline__contains='Lennon') & Q(entry__pubdate__year=2008) would 
be the filter(cond_a, cond_b).
Q(entry__headline__contains='Lennon') | Q(entry__pubdate__year=2008) would 
be the filter(cond_a).filter(cond_b).

The justification for **not** doing it this way, I suppose, would be that Q 
objects may not have existed at the time, or this was just never 
considered. The justification for not changing it to be this way now would 
be because it'd break user code everywhere.

I agree that the Q &/| logic would be more intuitive, but it's not 
something we can change at this point.

On Friday, 30 March 2018 08:26:44 UTC+11, Andrew Standley wrote:
>
> I have recently become acquainted with some ORM behaviour for reverse 
> relationships that "makes no sense", and I'm hoping someone can explain the 
> justification for the current behaviour. 
>
> This specifically relates to `filter` behaviour referenced in 29271 
> <https://code.djangoproject.com/ticket/29271>, and 16554 
> <https://code.djangoproject.com/ticket/16554> which seems tangentially 
> related to several issues with `exclude` (24421 
> <https://code.djangoproject.com/ticket/24421>, 14645 
> <https://code.djangoproject.com/ticket/14645>, 17315 
> <https://code.djangoproject.com/ticket/17315>) and aggregate expressions (
> 16603 <https://code.djangoproject.com/ticket/16603>, 19415 
> <https://code.djangoproject.com/ticket/19415>)
>
> Most of the confusion about 'intended' behaviour and confirmed 'bugged' 
> behaviour seems to relate to the ORM's use of joins for reverse 
> relationships.
> I think my personal confusion boils down to two questions.
>
> 1) Is there some fundamental limitation in the ORM that prevents reducing 
> the number of joins? Several of these tickets indicate how the ORM could 
> potentially produce similar results with queries that did not use multiple 
> joins. Why is that not desirable behaviour?
>
> 2) Why is the current behaviour of `filter` for multi-value relationships 
> 'intended'? I'm hoping I am missing something obvious but it seems to me 
> that `Q` objects would support the type of behaviour suggested in the 
> spanning 
> multi-valued relationships 
> <https://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships>
>  documentation 
> in a much more inituative manner. In a test case with models
>
> class Related(models.Model):
>     field = models.CharField(max_length=100)
>
> class Main(models.Model):
>     field_one = models.CharField(max_length=100)
>     field_two = models.CharField(max_length=100)
>     related = models.ForeignKey(Related, on_delete=models.CASCADE)
>
>
> both
>
> >>> Related.objects.filter(Q(main__field_two='2')|Q(main__field_one='1'))
>
> SQL:
> SELECT "test_app_related"."id", "test_app_related"."field" FROM 
> "test_app_related" INNER JOIN "test_app_main" ON ("test_app_related"."id"=
>  "test_app_main"."related_id") WHERE ("test_app_main"."field_two" = "2"
>  OR "test_app_main"."field_one" = "1")
>
> and
>
> >>> Related.objects.filter(main__field_two='2').filter(main__field_one='1'
> )
>
> SQL:
> SELECT "test_app_related"."id", "test_app_related"."field" FROM "test_app_
> related" INNER JOIN "test_app_main" ON ("test_app_related"."id"= 
> "test_app_main"."related_id") INNER JOIN "test_app_main" T3 ON ("test_app_
> related"."id" = T3."related_id") WHERE ("test_app_main"."field_two" = 
> "two" AND T3."field_one" = "one")
>
> Produce exactly the same results but the second seems to have an 
> unnecessary extra join, and directly contradicts the behaviour of filter 
> with non multi-valued fields.
>
>
>
> In short, could someone be kind enough to explain the justification for 
> all this weird behaviour with multi-value relationships?
>
>
> Cheers,
>   Andrew
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/81339adc-875e-48ac-a41f-4e45d0c26823%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to