Profile image for Brett C brettsky
App Engine lacks an equivalent to Django's SlugField property. This code is a (very rough) attempt at creating such a property for App Engine.
Language
Python
Tags
app engine django python
Favorited By
Profile image for Ian Lewis

SlugProperty for App Engine based on Django's SlugField

1 from google.appengine.ext import db 2 import re 3 4 5 class SlugProperty(db.StringProperty): 6 7 """A (rough) App Engine equivalent to Django's SlugField.""" 8 9 re_strip = re.compile(r'[^\w\s-]') 10 re_dashify = re.compile(r'[-\s]+') 11 12 def __init__(self, auto_calculate, **kwargs): 13 """Initialize a slug with the property to base it on. 14 15 The property passed in for auto_calculate should be the property object 16 itself from the model:: 17 18 class Spam(BaseModel): 19 name = db.StringProperty() 20 slug = SlugProperty(name) 21 22 """ 23 super(SlugProperty, self).__init__(**kwargs) 24 self.auto_calculate = auto_calculate 25 26 @classmethod 27 def slugify(yo_mama, value): 28 cleanup = yo_mama.re_strip.sub('', value).strip().lower() 29 return yo_mama.re_dashify.sub('-', cleanup) 30 31 def default_value(self): 32 """Cannot calculate a default value because of a lack of details for 33 use with the descriptor.""" 34 return super(SlugProperty, self).default_value() 35 36 def get_value_for_datastore(self, model_instance): 37 """Convert slug into format to go into the datastore.""" 38 value = self.auto_calculate.__get__(model_instance, None) 39 return self.slugify(value) 40 41 def validate(self, value): 42 """Validate the slug meets formatting restrictions.""" 43 # Django does [^\w\s-] to '', strips, lowers, then [-\s] to '-'. 44 if value and (value.lower() != value or ' ' in value): 45 raise db.BadValueError("%r must be lowercase and have no spaces" % 46 value) 47 return super(SlugProperty, self).validate(value)

Discussion

Three important points should be kept in mind when using this. One is that this is not heavily tested. It has worked for me so far, but only in minor testing situations. Two, realize that the slug is automatically calculated every time, so do not count on the slug to be stable if the property you attach it to changes. And three, do not try to access the slug field until you have put the model instance into the datastore! Because of the information given by App Engine to the default_value method it prevents the calculation of the slug from the property being relied upon.

Comments