Lee
Lee

Reputation: 8744

Context processors only update on server restart

I have a context processor that is database driven.

def on_air(request):              
    on_air = OnAir()              
    return {                      
        'on_air': {               
            'now': on_air.now(),  
            'next': on_air.next(),
        },                        
    }   

Edit: Here is the OnAir class

from collections import defaultdict

from datetime import datetime, time

from .models import ShowPage


def schedule():
    schedule = defaultdict(list)
    shows = ShowPage.objects.order_by(
        'weekday_start',
        'saturday_start',
        'sunday_start').all()

    for show in shows:
        for day in ('weekday', 'saturday', 'sunday',):
            if getattr(show, '{day}_start'.format(day=day)):
                schedule[day].append({
                    'show': show,
                    'start': getattr(show, '{day}_start'.format(day=day)),
                    'end': getattr(show, '{day}_end'.format(day=day)),
                })

    return schedule


class OnAir:

    def __init__(self, schedule=schedule()):
        self.schedule = schedule
        self.isoweekday = datetime.now().isoweekday()
        self.current_time = datetime.now().time()

    def now(self):
        shows = [item for item in self.schedule[self._today()]
                 if item['start'] <= self.current_time
                 and item['end'] > self.current_time]

        val = None
        if shows:
            val = shows[0]
        else:
            if self.current_time > time(12, 0):
                # If no shows are found and it is after midday,
                # then it means that the last show wraps over into the new day,
                # eg. from 11pm to 1am the next morning
                val = self._last_show_of_the_day(self._today())
            else:
                # It is the crack of dawn and yesterday's last show
                # started at say 11pm and carried through to say 3am today
                val = self._last_show_of_the_day(self._yesterday())

        return val['show'] if val else None

    def next(self):
        shows = [item for item in self.schedule[self._today()]
                 if item['start'] > self.current_time]

        val = None
        if shows:
            val = shows[0]
        else:
            val = self._first_show_of_the_day(self._tomorrow())

        return val['show'] if val else None

    def _isoweekday_to_key(self, isoweekday):
        if isoweekday == 0:
            isoweekday = 7

        if isoweekday == 8:
            isoweekday = 1

        val = 'weekday'

        if isoweekday == 6:
            val = 'saturday'

        if isoweekday == 7:
            val = 'sunday'

        return val

    def _today(self):
        return self._isoweekday_to_key(self.isoweekday)

    def _yesterday(self):
        return self._isoweekday_to_key(self.isoweekday - 1)

    def _tomorrow(self):
        return self._isoweekday_to_key(self.isoweekday + 1)

    def _first_show_of_the_day(self, today):
        today = self.schedule[today]
        return today[0] if today else None

    def _last_show_of_the_day(self, today):
        today = self.schedule[today]
        return today[-1] if today else None

If I update the database, and refresh the page, nothing changes. I have to restart the dev server for my changes to appear.

How can I fix this?

Upvotes: 0

Views: 63

Answers (1)

Alasdair
Alasdair

Reputation: 309039

The problem is in the __init__ method of your OnAir class.

class OnAir:
    def __init__(self, schedule=schedule()):

schedule() is evaluated once when the module is loaded, not every time that an OnAir instance is created as you might have expected.

You can fix this by changing the default to None, then creating the schedule inside the __init__ method.

class OnAir:
    def __init__(self, schedule=None):
        if schedule is None:
            schedule = schedule()
        ...

Upvotes: 3

Related Questions