Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django way to do conditional formatting

What is the correct way to do conditional formatting in Django?

I have a model that contains a date field, and I would like to display a list of records, but colour the rows depending on the value of that date field. For example, records that match today's date I want to be yellow, records that is before today I want green and ones after I want red.

Somewhere in Django you will need to do that comparison, comparing the current date with the date in the record.

I can see three different places that comparison could be done:

  1. Add a method to my model, for example, status(), that returns either 'past', 'present', 'future' and then use that in the template to colour the rows.
  2. In the view instead of returning a queryset to the template, pre-process the list and compare each record, build a new dict containing the 'past', 'present' and 'future' values to be used in the template
  3. Create a new template tag that does the comparison.

Which of these methods is the correct Django way of doing it? It sounds like conditional formating is something that would come up quite often, and since you can't do arbitrary comparisons in the template some other solution is needed.

The same would apply for simpler formatting rules, for example, if I wanted to display a list of student grades, and I wanted to make the ones higher than 80% green and the ones below 30% red.

like image 812
Andre Miller Avatar asked Jul 01 '09 11:07

Andre Miller


2 Answers

I'm a big fan of putting ALL "business" logic in the view function and ALL presentation in the templates/CSS.

Option 1 is ideal. You return a list of pairs: ( date, state ), where the state is the class name ("past", "present", "future").

Your template then uses the state information as the class for a <span>. Your CSS then provides the color coding for that span.

You are now free to change the rules without breaking the template. You can change the CSS without touching HTML or Python code.

{% for date,state in the_date_list %}
    <span class="{{state}}">date</span>
{% endfor %}
like image 94
S.Lott Avatar answered Sep 20 '22 16:09

S.Lott


I had a very similar requirement; as this is pretty connected to the business logic, I have added a model method to manage this kind of information, to be used then in the template:

{% if not bug.within_due_date %}bgcolor="OrangeRed"{% endif %}

It could also be obtained through a template tag or filter; but in my case, I felt the best place for the logic was inside the model; I would suggest you analyzing it in the same way.

like image 20
rob Avatar answered Sep 19 '22 16:09

rob