Rendering Form Fields That Are Passed To Context Inside Of An Object

19 views
Skip to first unread message

David McWilliams

unread,
Apr 8, 2016, 6:21:24 PM4/8/16
to Django users
tl:dr -- How do I explicitly render the fields in a form that's passed to the context dictionary within an object?

I'm building a page right now that shows a list of documents to the user.  Each document has a type, a status, a list of images associated with it, and finally a document update form with a few fields in it.  Because all of these pieces of data belong together, I created a class to group them for display (this is a simplified version for example only):

class Document:
   
def __init__(self, doc_type, doc_status):
       
self.doc_type = doc_type
       
self.doc_status = doc_status
       
self.update_form = DocUpdateForm()

def doc_view(request):
   
# ... some other stuff to get the raw data ...

    documents
= []

   
for raw_doc in raw_document_data:
        documents
.append(Document(raw_doc.doc_type, raw_doc.doc_status))

    context
['documents'] = documents

   
return render_to_response('doc_list.html', context)

This all worked fine, because then in my template I was able to do something nice and simple like this:

...
<h2>Documents</h2>
<table>
  <tr><th>Document Type</
th><th>Document Status</th><th>Update</th></tr>
 
{% for doc in documents %}
   
<tr>
     
<td>{{ doc.doc_type }}</td>
     
<td>{{ doc.doc_status }}</td>
     
<td><form>{{ doc.update_form }}<input type='submit'/></form></td>
   
</tr>
  {% endfor %}
</
table>

Piece of cake, right?

Well, now we want to change the page so that some of the form fields are inside of one div, and some inside of another one so that they can be next to one another instead of oriented vertically.  I consulted the Django documentation here: https://docs.djangoproject.com/en/1.9/topics/forms/#rendering-fields-manually and decided to render each of the fields myself.  This resulted in something like:

...
<h2>Documents</h2>
<table>
  <tr><th>Document Type</
th><th>Document Status</th><th>Update</th></tr>
 
{% for doc in documents %}
   
<tr>
     
<td>{{ doc.doc_type }}</td>
     
<td>{{ doc.doc_status }}</td>
     
<td><form><div>{{ doc.update_form.field_1 }}</div>
               
<div>{{ doc.update_form.field_2 }}</div>
               
<input type='submit'/></form></td>
   
</tr>
  {% endfor %}
</
table>


Unfortunately, all this does is render the text "doc.update_form.field_1" instead of the form field.  It's the same behavior that I see when I accidentally try to reference a key that doesn't exist in the context dictionary.

I can, of course, just write the form fields HTML by hand . . . but goshdarnit, I'm a developer, and I want to know why the lazy way isn't working.  Do I need to reference the form fields differently than the documentation suggests?  Is it because I'm passing the forms to the context inside of another object?  Should I be learning how to use formsets and/or fieldsets?

This app uses Django 1.8, in case that's important.

jorr...@gmail.com

unread,
Apr 9, 2016, 10:25:40 AM4/9/16
to Django users
Are you sure you have the name of the fields correct? According to the documentation {{ form.fieldname }} should do what you want. It sounds like formsets would be more appropriate for what you're trying to achieve though.

And yeah, if you're going to go that specific you might as well render all the fields completely manually :)

David McWilliams

unread,
Apr 10, 2016, 11:53:29 AM4/10/16
to Django users
I'm pretty sure that I have them correct -- it'd be weird if I'd managed to include a typo in all six fields of the real form -- but I'll double check it on Monday when I get back into the office.  And thanks, I'll look into Formsets too!
Reply all
Reply to author
Forward
0 new messages