views:

611

answers:

1

I have a database object called manor_stats, with around 30 fields. For most rows, most of these fields will be null.

In my template, I'd like to loop through all the fields in the row, and print info for only the fields that aren't null.

For example, there's a field called "name": I'd like to print <li>Name: {{ manor_stats.name }}</li> in the template ONLY for those objects where the field isn't null. Ideally I'd like to pull in "Name: " from somewhere automatically too, rather than specifying it.

I know I could use {% if manor_stats.name %} to check whether each field is null, but I don't want to do that 30 times for all the fields.

Here's what I have in views.py:

manor_stats = Manors.objects.get(idx=id)
return render_to_response('place.html', { 'place' : place, 'manor_stats' : manor_stats }, context_instance = RequestContext(request))

And then in place.html, I'd like to have something that works approximately like this (pseudocode, with ??? indicating the bits that I don't know how to do):

{% if manor_stats %} 
<ul>
 {% for manor_stats.property??? in manor_stats %} 
  {% if manor_stats.property %} 
   <li>{{ manor_stats.property.field_name??? }} {{ manor_stats.property.value??? }}</li>
  {% endif %}
 {% endfor %
{% endif %}

Hope that makes sense...

+4  A: 

You could add a method to your Manors model that will return all the field values, from there you can just loop over these values in your template checking to see if the value isn't null.

-- models.py

class Manors(models.Model)
  #field declarations

  def get_fields(self):
    return [(field.name, field.value_to_string(self)) for field in Manors._meta.fields]

-- manor_detail.html

{% for name, value in manor_stats.get_fields %}
  {% if value %}
    {{ name }} => {{ value }}
  {% endif %}
{% endfor %}
mountainswhim
Works perfectly - exactly what I was looking for. Thank you!
AP257
Do you know how I could return field.verbose_name alongside the value somehow? I guess it's just a question of the right Django syntax, but I'm baffled :(
AP257
I made some changes to my original answer. The name attribute attached to field should give you what you want.
mountainswhim
Thank you again! Does just what's needed.
AP257
Very elegant. If you want a little more control (such as the ability to resolve picklists/choices fields or to exclude certain fields, see this somewhat more elaborate version of a model method that gets all fields and returns them to the template: http://stackoverflow.com/questions/2170228/django-iterate-over-model-instance-field-names-and-values-in-template/2226150#2226150
shacker