Lysender
Lysender

Reputation: 179

AppEngine Python - how to deal with cached object values

Newbie question.

So I have this handler for a page that appends some CSS/JS files. The problem is that subsequent requests will result to values appended over and over again.

Example:

def action_index(self):
    self.template = 'index.html'

    extra_styles = ['/media/css/jquery.lightbox-0.5.css']
    extra_scripts = ['/media/js/jquery.lightbox-0.5.min.js', '/media/js/project.js']

    for style in extra_styles:
        self.styles.append(style)

    for script in extra_scripts:
        self.scripts.append(script)

How do you usually handle this in platform like Google AppEngine since I'm coming from PHP background where objects only lives within the current request.

Thanks

As requested, here is the base class:

Base controller

from google.appengine.ext.webapp import template 

import os
import config
import datetime

class BaseController(object):

    request = None
    response = None
    action = 'index'
    method = 'get'
    params = []
    template_values = {}
    template_dir = None
    template = None

    default_styles = ['/media/bootstrap/css/bootstrap.min.css', '/media/css/style.css']
    default_scripts = ['/media/js/jquery-1.6.4.min.js']

    styles = []
    scripts = []

    def __init__(self, request, response, *args, **kwargs):
        self.request = request
        self.response = response

        self.action = 'index'
        if 'action' in kwargs and kwargs['action']:
            self.action = kwargs['action']

        self.method = 'get'
        if 'method' in kwargs and kwargs['method']:
            self.method = kwargs['method']

        self.params = []
        if 'params' in kwargs and kwargs['params']:
            if isinstance(kwargs['params'], list):
                self.params = kwargs['params']

        # Initialize template related variables
        self.template_values = {}
        self.styles = list(self.default_styles)
        self.scripts = list(self.default_scripts)

    def pre_dispatch(self):
        pass

    def post_dispatch(self):
        if self.template is not None and self.template_dir is not None:
            # Populate current year
            dt = datetime.date.today()
            self.template_values['current_year'] = dt.year

            # Populate styles and scripts
            self.template_values['styles'] = self.styles
            self.template_values['scripts'] = self.scripts

            path = os.path.join(config.template_dir, self.template_dir, self.template)
            self.response.out.write(template.render(path, self.template_values))

    def run_action(self):
        action_name = 'action_' + self.action
        if hasattr(self, action_name):
            action = getattr(self, action_name)
            action()
        else:
            raise Http404Exception('Controller action not found')

    def dispatch(self):
        self.pre_dispatch()
        self.run_action()
        self.post_dispatch()

class HttpException(Exception):
    """Http Exception"""
    pass

class Http404Exception(HttpException):
    """Http 404 exception"""
    pass

class Http500Exception(HttpException):
    """Http 500 exception"""
    pass

And the child class

import datetime

from dclab.lysender.controller import BaseController

class ProjectsController(BaseController):

    template_dir = 'projects'

    def action_index(self):
        self.template = 'index.html'
        self.styles.extend(['/media/css/jquery.lightbox-0.5.css'])
        self.scripts.extend([
            '/media/js/jquery.lightbox-0.5.min.js',
            '/media/js/project.js'
        ])

My fault was that I'm assigning a list to another list via reference, not cloning the list. I'm not so aware of this behavior that's why it made me scratching my head the whole night.

Upvotes: 0

Views: 169

Answers (1)

Nick Johnson
Nick Johnson

Reputation: 101149

You're declaring a whole lot of variables directly under the class definition. Doing this does not define instance members, as you seem to be expecting, but rather defines class variables - the equivalent of 'static' in a language like Java.

Instead of declaring things as class variables, initialize your values inside the constructor - the __init__ method of your class.

I would also strongly recommend using an existing web framework like webapp2 rather than inventing your own.

Upvotes: 2

Related Questions