views:

54

answers:

1

Hi Guys,

Wondering if it's possible to change a value returned from a queryset before sending it off to the template. Say for example you have a bunch of records

Date | Time | Description
10/05/2010 | 13:30 | Testing...

etc...

However, based on the day of the week the time may change. However this is static. For example on a monday the time is ALWAYS 15:00.

Now you could add another table to configure special cases but to me it seems overkill, as this is a rule. How would you replace that value before sending it to the template?

I thought about using the new if tags (if day=1), but this is more of business logic rather then presentation.

Tested this in a custom template tag

def render(self, context):
    result = self.model._default_manager.filter(from_date__lte=self.now).filter(to_date__gte=self.now)
    if self.day == 4:
        result = result.exclude(type__exact=2).order_by('time')
    else:
        result = result.order_by('type')
    result[0].time = '23:23:23'
    context[self.varname] = result
    return ''

However it still displays the results from the DB, is this some how related to 'lazy' evaluation of templates?

Thanks!

Update Responding to comments below: It's not stored wrong in the DB, its stored Correctly However there is a small side case where the value needs to change.

So for example I have a From Date & To date, my query checks if todays date is between those. Now with this they could setup a from date - to date for an entire year, and the special cases (like mondays as an example) is taken care off. However if you want to store in the DB you would have to capture several more records to cater for the side case. I.e you would be capturing the same information just to cater for that 1 day when the time changes. (And the time always changes on the same day, and is always the same)

Update with Solution (Based on answer by KillianDS below) In models.py i defined a custom property:

@property
def get_corrected_time(self):
    from datetime import time
    day = datetime.now().weekday()
    if day == 0 or day == 1:
        self.time = time(12,30)
    return self.time

and in the template

   {{ object.get_corrected_time|time:"P" }}

The reason for returning a datetime.time object rather then a string is, django's default date & time filters will not work on a string.

+3  A: 

Okay, without any precise example (a simple model & clear use case would help), I can't really be sure, but I guess this is what you want to do. In your model definition, add something like this:

@property
def get_corrected_time(self):
    if today_is_monday:
        return '13:30'
    return str(self.time)

in your template you can perfectly call this as {{ object.get_corrected_time }}

Now I see in your template tag you want to do this for example only on the first element in a queryset, you can easily do this as follows in the template (you could also do it in the view method):

{% for object in list %}
{% if forloop.first %}
    {{ object.get_corrected_time }}
{% else %}
    {{ object.time }}
{% endif %}
{% endfor %}
KillianDS
Thanks this worked!
izzy