Archive for Tag "appengine"

Adding key_name when saving appengine djangoforms

// You cannot set key_name for models in appengine's djangoforms
// Now you can!

form = TagForm(request.POST or None, instance=tag)
errors = form.errors
if not errors:
  try:
    tag = form.save(commit=False)
  except ValueError, err:
    errors['__all__'] = unicode(err)
  if not errors:
    key_name = 'tag:%s' % tag.name
    saved_tag = Tag(key_name=key_name, **dict([(prop, getattr(tag, prop)) for prop in Tag.properties()]))
    saved_tag.save()

Unique Fields on Google Appengine djangoforms.ModelForm

// this is how i check for dupes

def isUnique(form, field, data):
    """Validates that a value is unique for a field.
    """
    if not isinstance(form, djangoforms.ModelForm):
        raise TypeError, u'The instance passed to isUnique is not a subclass of djangoforms.ModelForm'

    model = form._meta.model
    matching_obj = model.gql("WHERE " + field + " = :1", data).get()
    if not matching_obj:
        return data

    if form.instance and form.instance.key() == matching_obj.key():
        return data
    
    raise forms.ValidationError(u'%(optname)s with this %(fieldname)s already exists.' % {'optname':model.kind(), 'fieldname':field})

//how to use this

class TagForm(djangoforms.ModelForm):
    def clean_name(self):
        if 'name' in self.clean_data:
            value = self.clean_data['name'].strip()
            if value:
                return isUnique(self, 'name', value)
        raise forms.ValidationError('Name is required')
    class Meta:
        model = models.Tag

Django Cache Decorator

// simple decorator for caching result

from django.core.cache import cache

def cached(cache_key):
    """Cache decorator
    """
    def doCache(func):
        def _get_cached(*args, **kwargs):
            result = cache.get(cache_key)
            if result is None:
                result = func(*args, **kwargs)
                cache.set(cache_key, result)

            return result
        return _get_cached
    return doCache

def delete_cached(cache_key):
    """Delete cache decorator
    """
    def doDeleteCache(func):
        def _delete_cached(*args, **kwargs):
            result = func(*args, **kwargs)
            cache.delete(cache_key)
            return result
        return _delete_cached
    return doDeleteCache

// you can use this decorator into your models.
// for example

from google.appengine.ext import db
class Tag(db.Model):
    """The snippet tags
    """
    name = db.StringProperty()
    description = db.TextProperty()
    entrycount = db.IntegerProperty(default=0)
    
    @staticmethod
    @cached('tags')
    def getall():
        return [tag for tag in Tag.all()]

    @delete_cached('tags')
    def save(self):
        """Will save the current tag and invalidate the cache automatically"""
        self.put()
  
    @delete_cached('tags')
    def remove(self):
        self.delete()

Fulltext Search on appengine models

// fulltext search support on appengine models

from google.appengine.ext import search

class Tag(search.SearchableModel):
    """The snippet tags
    """
    name = db.StringProperty()
    description = db.TextProperty()

// then, use it like this

for tag in Tag.all().search("sometag").order('name').fetch(10):
  print tag.name

Using django with appengine

django_bootstrap.py

import logging, os, sys
from google.appengine.ext.webapp import util

# Force Django to reload its settings.
from django.conf import settings
settings._target = None

# Must set this env var before importing any part of Django
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

import django.core.handlers.wsgi
import django.core.signals
import django.db
import django.dispatch.dispatcher

def log_exception(*args, **kwds):
    logging.exception('Exception in request:')

# Log errors.
django.dispatch.dispatcher.connect(
    log_exception, django.core.signals.got_request_exception)

# Unregister the rollback event handler.
django.dispatch.dispatcher.disconnect(
    django.db._rollback_on_exception,
    django.core.signals.got_request_exception)

def main():
    application = django.core.handlers.wsgi.WSGIHandler()
    util.run_wsgi_app(application)

if __name__ == '__main__':
    main()

Django Cache using Appengine Memcache

cache_backend.py

from django.core.cache.backends.base import BaseCache
from google.appengine.api.memcache import Client

class CacheClass(Client, BaseCache):
    def __init__(self, default_timeout=300):
        Client.__init__(self)
        BaseCache.__init__(self, {'timeout': default_timeout})

    def get(self, key, default=None):
        val = super(CacheClass, self).get(key)
        if val is None:
            return default
        return val

    def get_many(self, keys, key_prefix=''):
        return self.get_multi(keys, key_prefix)

    def set(self, key, value, timeout=0):
        return super(CacheClass, self).set(key, value,
            timeout or self.default_timeout)
            
    def delete(self, key):
        return super(CacheClass, self).delete(key)

    def set_many(self, mapping, timeout=0, key_prefix=''):
        return self.set_multi(mapping, timeout, key_prefix)

    def delete_many(self, keys, seconds=0, key_prefix=''):
        return self.delete_multi(keys, seconds, key_prefix)

Add this inside your django_bootstrap.py

from cache_backend import CacheClass
from django.core import cache
from google.appengine.api import memcache
cache.cache = CacheClass()
memcache.setup_client(cache.cache)