#3371: Filter to get dict's value by key name (for the purpose of enabling
variable lookups in the template)
-------------------------------------+-------------------------------------
     Reporter:  Alex Dedul           |                    Owner:  nobody
         Type:  New feature          |                   Status:  new
    Component:  Template system      |                  Version:  master
     Severity:  Normal               |               Resolution:
     Keywords:  template filter      |             Triage Stage:
  dict key                           |  Unreviewed
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  1                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by anonymous):

 * status:  closed => new
 * severity:   => Normal
 * resolution:  wontfix =>
 * easy:   => 1
 * ui_ux:   => 0
 * type:   => New feature
 * stage:  Design decision needed => Unreviewed


Comment:

 Dear "Django's lead developers":

 Being unable to perform variable lookups in the template is the bane of
 Django.
 Please be aware that after reviewing #12486, #1495, #959, and #577; I have
 determined that #3371 most appropriately addresses this source of Django's
 impotence. The individuals responsible for closing this ticket (@jacob,
 @ubernostrum) have provided nothing but non sequitur as motivation for its
 closing.  I find it necessary to reopen #3371, and I will continue to
 reopen it until Django is capable of performing variable lookups in the
 template, or until a SOUND reason is given for insisting that Django
 inflict such an undue handicap on perfectionists with deadlines.

 For the purpose of exemplifying the need for variable lookups in the
 template, consider a list of students ["Bob", ..., "Alice"] who enrol in
 courses ["Course1", ..., "CourseN"] and earn final marks of {"Bob" :
 {"Course1" : bobs_mark_for_course1, ..., "CourseN" :
 bobs_mark_for_courseN}, ..., "Alice" : {"Course1" :
 alices_mark_for_course1, ..., "CourseN" : alices_mark_for_courseN}}

 Displaying this table of information is a template level concern, and
 should be performed trivially as follows:

 Step 1 - In the views.py:
   c[!''students!''] = ["Bob", ..., "Alice"] # NOTE student names are
 unique in this example!
   c[!''courses!''] = ["Course1", ..., "CourseN"] # ditto the above comment
 for student names
   c[!''marks!''] = {"Bob" : {"Course1" : bobs_mark_for_course1, ...,
 "CourseN" : bobs_mark_for_courseN}, ..., "Alice" : {"Course1" :
 alices_mark_for_course1, ..., "CourseN" : alices_mark_for_courseN}}

   return render(request, c, "display.html")

 Step 2 - In the template display.html:
   <table>
     <tr>
       <td>Student Name</td>
       {% for course in courses %}
         <td>{{course}} Grade</td>
       {% endfor %}
     </tr>

     {% for student in students %}
       <tr>
         <td>{{student}}</td>
         {% for course in courses %}
           <td>{{marks.student.course}}</td> {# ALERT Variable lookup! #}
         {% endfor %}
       </tr>
     {% endfor %}
   </table>
 
------------------------------------------------------------------------------------------------------------------------------------------------------------

 Sadly, it appears that this trivial exercise in templating is "out of
 scope" (@jacob) or even "impolite" (@ubernostrum). While not providing any
 alternatives to (or even any sound reasons for rejecting) @nullie's fix,
 one might speculate that the cited "Django's lead developers" would rather
 we perform such templating in the views.py:

 Step 1 - In the views.py:
 students = ["Bob", ..., "Alice"] # NOTE student names are unique in this
 example!
 courses = ["Course1", ..., "CourseN"] # ditto the above comment for
 student names
 marks = {"Bob" : {"Course1" : bobs_mark_for_course1, ..., "CourseN" :
 bobs_mark_for_courseN}, ..., "Alice" : {"Course1" :
 alices_mark_for_course1, ..., "CourseN" : alices_mark_for_courseN}}

 table_to_display = []
 html = table_to_display.append
 html("<table><tr><td>Student Name</td>")
 for course in courses:
   html("<td>")
   html(course)
   html(" Grade</td>"
 html("</tr>")
 for student in students:
   html("<tr><td>")
   html(student)
   html("</td>")
   for course in courses:
     html("<td>")
     html(marks[student][course])
     html("</td>")
   html("</tr>")
 html("</table>")

 c[!''marks_table!''] = "".join(table_to_display)
 return render(request, c, "display.html")

 Step 2 - In the template display.html:
 {{marks_table|safe}}

 I'm sure that any person involved in a web-development project would agree
 that styling/upgrading/extending or otherwise maintaining under this
 paradigm is a doomed and futile effort.

 Using @nullie's fix, our task is accomplished with the following:
 Step 1 - In the views.py
   c[!''students!''] = ["Bob", ..., "Alice"] # NOTE student names are
 unique in this example!
   c[!''courses!''] = ["Course1", ..., "CourseN"] # ditto the above comment
 for student names
   c[!''marks!''] = {"Bob" : {"Course1" : bobs_mark_for_course1, ...,
 "CourseN" : bobs_mark_for_courseN}, ..., "Alice" : {"Course1" :
 alices_mark_for_course1, ..., "CourseN" : alices_mark_for_courseN}}

   return render(request, c, "display.html")


 Step 2 - In the template display.html:
   <table>
     <tr>
       <td>Student Name</td>
       {% for course in courses %}
         <td>{{course}} Grade</td>
       {% endfor %}
     </tr>
     {% for student in students %}
       <tr>
         <td>{{student}}</td>
         {% for course in courses %}
           <td>
             {{marks|get:student|get:course}} {# Chaining filters emulates
 the nested variable lookup #}
           </td>
         {% endfor %}
       </tr>
     {%  endfor %}
   </table>

 In further defence of @nullie's fix: note that when the data does not
 exist, the filter simply returns None. This is advantageous because we can
 test for None in the template using an if-else block. When None is
 encountered, we make the TEMPLATE level decision of what content shall be
 displayed. We may then display that content (even change our minds later)
 without ever concerning ourselves with python code.

 It is my position that the example of students and courses provided above
 is hardly a manifestation of an "out of scope" use-case for Django
 projects. @nullie has proposed a solution and it was rejected without any
 sound criticism. A blind eye is being turned on perfectionists with
 deadlines. Altogether, I trust that I have demonstrated a sufficient
 condition for reopening #3371 (regardless of how impolite @ubernostrum
 feels such a sufficient condition is). Please expect #3371 to continue
 being reopened until a sufficient condition is provided for closing it.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/3371#comment:10>
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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/068.1379c0903e14137742ffdbd9dd2b2e5a%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to