views:

322

answers:

1

I'm adding search to an existing Django site, using Haystack with a Solr backend. I want my search to work across several different models, and return a single set of of results.

When iterating through the results, I would like to format each result based on what model type it is -- e.g. if the result is an Apple, use one result template, but if it's an Orange, use a different template.

So far, I'm just using a slightly modified version of the example search template. In the template, the results come in page.object_list:

{% if page.object_list %}
  <ul>
    {% for result in page.object_list %}
        <li>
            {% if (isinstance(result.object, Apple)) %}
              Apple: {{ result.object.titlefield_for_apple }}
            {% else %}
              Orange: {{ result.object.otherfield_for_orange }}
            {% endif %}
        </li>
    {% endfor %}
  </ul>
{% else %}
    <p>No results found.</p>
{% endif %}

This doesn't work, apparently because isinstance() isn't available inside a template. So, how can I control template logic based on the the Model type of an object? Is there another function that I can use inside a template which does the same thing?

I suppose I could test various fields of the object (if result.object.otherfield_for_orange) to identify it, but that seems inelegant. I bet this could be done with custom template tags, but I've no experience with those.

+3  A: 

Ok, duh, immediately after asking this I dug deeper into the Haystack docs, and found exactly what I need:

{% ifequal result.model_name 'apple' %}
  Apple: {{ result.object.titlefield_for_apple }}
{% else %}
  Orange: {{ result.object.otherfield_for_orange }}
{% endifequal %}

Which totally makes sense, because of course Haystack should pass the types back with the results. It actually passes several versions of the type info, for easy use in the template:

  • model_name - The model’s name.
  • model - The model class.
  • verbose_name - A prettier version of the model’s class name for display.
Cashman