diff -r 620f9b141567 -r e310681d5509 app/soc/models/base.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/soc/models/base.py Wed Aug 27 21:21:44 2008 +0000 @@ -0,0 +1,84 @@ +#!/usr/bin/python2.5 +# +# Copyright 2008 the Melange authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Module containing enhanced db.Model classes. + +The classes in this module are intended to serve as base classes for all +Melange Datastore Models. +""" + +__authors__ = [ + '"Todd Larsen" ', +] + + +from google.appengine.ext import db + +from soc.views.helpers import forms_helpers + + +class ModelWithFieldAttributes(db.Model): + """A db.Model extension that provides access to Model properties attributes. + + Due to the way the Property class in Google App Engine implements __get__() + and __set__(), it is not possible to access attributes of Model properties, + such as verbose_name, from within a Django template. This class works + around that limitation by creating an inner Form class per Model class, + since an unbound Form object contains (most of?) the property attributes + attached to each corresponding Form field. + + Some are attributes are renamed during the conversion from a Model Property + to a Form field; for example, verbose_name becomes label. This is tolerable + because any actual Form code refers to these new names, so they are should + be familiar to view creators. + """ + + _fields_cache = None + + @classmethod + def fields(cls): + """Called by the Django template engine during template instantiation. + + Since the attribute names use the Form fields naming instead of the + Property attribute naming, accessing, for example: + {{ entity.property.verbose_name }} + is accomplished using: + {{ entity.fields.property.label }} + + Args: + cls: Model class, so that each Model class can create its own + unbound Form the first time fields() is called by the Django + template engine. + + Returns: + A (created-on-first-use) unbound Form object that can be used to + access Property attributes that are not accessible from the + Property itself via the Model entity. + """ + if not cls._fields_cache or (cls != cls._fields_cache.__class__.Meta.model): + class FieldsProxy(forms_helpers.DbModelForm): + """Form used as a proxy to access User model properties attributes. + """ + + class Meta: + """Inner Meta class that pairs the User Model with this "form". + """ + #: db.Model subclass for which to access model properties attributes + model = cls + + cls._fields_cache = FieldsProxy() + + return cls._fields_cache