#27936: ASCII Art for docs "Spanning multi-valued relationships"
--------------------------------+--------------------------------------
     Reporter:  Thomas Güttler  |                    Owner:  nobody
         Type:  Uncategorized   |                   Status:  new
    Component:  Documentation   |                  Version:  1.10
     Severity:  Normal          |               Resolution:
     Keywords:                  |             Triage Stage:  Unreviewed
    Has patch:  0               |      Needs documentation:  0
  Needs tests:  0               |  Patch needs improvement:  0
Easy pickings:  0               |                    UI/UX:  0
--------------------------------+--------------------------------------

Comment (by Josh Smeaton):

 I think there's definitely scope to improve the docs around multi valued
 relationships, but I don't think ASCII art (or that diagram) is really the
 right way of doing it. For some added confusion, the docs fail to mention
 that duplicates are possible with the second query (with multiple filters)
 if there is an entry with the headline Lennon AND it was posted in 2008.
 It seems the docs go through a lot of effort to avoid mentioning that a
 second filter causes the query to create a second join to the same table.

 I'm not proposing new language for this myself, but I've seen many an
 experienced developer get caught by this without understanding what was
 actually happening with the underlying query. I'd very much like to see
 these docs improved in some way.

 Here's some shell output for those curious about what's happening:

 {{{

 In [1]: from datetime import date
 In [2]: d2008 = date(2008, 6, 6)
 In [3]: d2009 = date(2009, 6, 6)
 In [4]: both = Blog.objects.create(name='Match Both')

 In [5]: Entry.objects.create(blog=both, headline='1 Lennon 1',
 body_text='body', pub_date=d2008)
 Out[5]: <Entry: Entry object>

 In [6]: Entry.objects.create(blog=both, headline='2 Lennon 2',
 body_text='body', pub_date=d2009)
 Out[6]: <Entry: Entry object>

 In [7]: Entry.objects.create(blog=both, headline='3 Blah 3',
 body_text='body', pub_date=d2008)
 Out[7]: <Entry: Entry object>

 In [8]: Blog.objects.filter(entry__headline__contains='Lennon',
 entry__pub_date__year=2008)
 Out[8]: <QuerySet [<Blog: Match Both>]>

 In [9]: justdate = Blog.objects.create(name='Match Date Only')

 In [10]: Entry.objects.create(blog=justdate, headline='4 Blah 4',
 body_text='body', pub_date=d2008)
 Out[10]: <Entry: Entry object>

 In [11]: justheadline = Blog.objects.create(name='Match Headline Only')

 In [12]: Entry.objects.create(blog=justheadline, headline='5 Lennon 5',
 body_text='body', pub_date=d2009)
 Out[12]: <Entry: Entry object>

 In [13]: Blog.objects.filter(entry__headline__contains='Lennon',
 entry__pub_date__year=2008)
 Out[13]: <QuerySet [<Blog: Match Both>]>

 In [14]:
 
Blog.objects.filter(entry__headline__contains='Lennon').filter(entry__pub_date__year=2008)
 Out[14]: <QuerySet [<Blog: Match Both>, <Blog: Match Both>, <Blog: Match
 Both>, <Blog: Match Both>]>

 }}}

 And the queries:

 {{{

 # Blog.objects.filter(entry__headline__contains='Lennon',
 entry__pub_date__year=2008)

 SELECT
   "scratch_blog"."id",
   "scratch_blog"."name",
   "scratch_blog"."tagline"
 FROM "scratch_blog"
   INNER JOIN "scratch_entry" ON ("scratch_blog"."id" =
 "scratch_entry"."blog_id")
 WHERE (
   "scratch_entry"."pub_date" BETWEEN '2008-01-01' :: DATE AND '2008-12-31'
 :: DATE)
   AND "scratch_entry"."headline" LIKE '%Lennon%'
 );


 #
 
Blog.objects.filter(entry__headline__contains='Lennon').filter(entry__pub_date__year=2008)

 SELECT
   "scratch_blog"."id",
   "scratch_blog"."name",
   "scratch_blog"."tagline"
 FROM "scratch_blog"
   INNER JOIN "scratch_entry" ON ("scratch_blog"."id" =
 "scratch_entry"."blog_id")
   INNER JOIN "scratch_entry" T3 ON ("scratch_blog"."id" = T3."blog_id")
 WHERE (
     "scratch_entry"."headline" LIKE '%Lennon%'
 AND T3."pub_date" BETWEEN '2008-01-01'::date AND '2008-12-31'::Date)
 }}}

--
Ticket URL: <https://code.djangoproject.com/ticket/27936#comment:1>
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 post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/065.a4985616c7085d921b56510d20956c8f%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to