# HG changeset patch # User Todd Larsen # Date 1223078389 0 # Node ID 56e1c1721299c8c1ddc3724a467b18174d19569e # Parent b97d08ebac0eed3ae164d1d368b0724b4c778a88 Move helpers/forms_helpers.py to helper/forms.py. Patch by: Todd Larsen Review by: to-be-reviewed diff -r b97d08ebac0e -r 56e1c1721299 app/soc/models/base.py --- a/app/soc/models/base.py Fri Oct 03 23:24:12 2008 +0000 +++ b/app/soc/models/base.py Fri Oct 03 23:59:49 2008 +0000 @@ -27,7 +27,8 @@ from google.appengine.ext import db -from soc.views.helpers import forms_helpers +from soc.views import helper +import soc.views.helper.forms class ModelWithFieldAttributes(db.Model): @@ -69,7 +70,7 @@ Property itself via the Model entity. """ if not cls._fields_cache or (cls != cls._fields_cache.__class__.Meta.model): - class FieldsProxy(forms_helpers.DbModelForm): + class FieldsProxy(helper.forms.DbModelForm): """Form used as a proxy to access User model properties attributes. """ diff -r b97d08ebac0e -r 56e1c1721299 app/soc/views/helper/forms.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/soc/views/helper/forms.py Fri Oct 03 23:59:49 2008 +0000 @@ -0,0 +1,172 @@ +#!/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. + +"""Helpers used to display various views that are forms. +""" + +__authors__ = [ + '"Chen Lunpeng" ', + '"Todd Larsen" ', + ] + + +from google.appengine.ext.db import djangoforms + +from django import newforms as forms +from django.utils import safestring + + +class DbModelForm(djangoforms.ModelForm): + """Subclass of Django ModelForm that fixes some label and help_text issues. + + The default behavior of ModelForm is to use the verbose_name in all + lowercase, capitalizing only the first character, as the displayed field + label. This class uses verbose_name unaltered as the visible field label + instead. + + The Property classes used by the App Engine Datastore do not have a + help_text parameter to their constructor. In a Model class, a help_text + attribute *can* be added to the property after it is created, but the + help text will not be automatically passed along to the Django ModelForm. + This class detects the presence of a help_text attribute and adds it to + the corresponding form field object. + + ugettext_lazy() proxies used for internationalization in the Model will + still work correctly with this new behavior, as long as the original + strings are used as the translation keys. + """ + + def __init__(self, *args, **kwargs): + """Fixes label and help_text issues after parent initialization. + + Args: + *args, **kwargs: passed through to parent __init__() constructor + """ + super(DbModelForm, self).__init__(*args, **kwargs) + + for field_name in self.fields.iterkeys(): + # Since fields can be added only to the ModelForm subclass, check to + # see if the Model has a corresponding field first. + if hasattr(self.Meta.model, field_name): + model_prop = getattr(self.Meta.model, field_name) + + # Check if the Model property defined verbose_name, and copy that + # verbatim to the corresponding field label. + if hasattr(model_prop, 'verbose_name'): + self.fields[field_name].label = model_prop.verbose_name + + # Check if the Model property added help_text, and copy that verbatim + # to the corresponding field help_text. + if hasattr(model_prop, 'help_text'): + self.fields[field_name].help_text = model_prop.help_text + + +class SelectQueryArgForm(forms.Form): + """URL query argument change control implemented as a Django form. + """ + + ONCHANGE_JAVASCRIPT_FMT = ''' + +''' + + def __init__(self, page_path, arg_name, choices, field_name, + *form_args, **form_kwargs): + """ + Args: + page_path: (usually request.path) + arg_name: the URL query parameter that determines which choice is + selected in the selection control + choices: list (or tuple) of value/label string two-tuples, for example: + (('10', '10 items per page'), ('25', '25 items per page')) + field_name: name of the selection field in the form + *form_args: positional arguments passed on to the Form base + class __init__() + *form_kwargs: keyword arguments passed on to the Form base + class __init__() + """ + super(SelectQueryArgForm, self).__init__(*form_args, **form_kwargs) + + self._script = safestring.mark_safe(self.ONCHANGE_JAVASCRIPT_FMT % { + 'arg_name': arg_name, 'page_path': page_path,}) + + onchange_js_call = 'changeArg_%s(this)' % arg_name + + self.fields[field_name] = forms.ChoiceField( + label='', choices=choices, + widget=forms.widgets.Select(attrs={'onchange': onchange_js_call})) + + def as_table(self): + """Returns form rendered as HTML rows -- with no
. + + Prepends -''' - - def __init__(self, page_path, arg_name, choices, field_name, - *form_args, **form_kwargs): - """ - Args: - page_path: (usually request.path) - arg_name: the URL query parameter that determines which choice is - selected in the selection control - choices: list (or tuple) of value/label string two-tuples, for example: - (('10', '10 items per page'), ('25', '25 items per page')) - field_name: name of the selection field in the form - *form_args: positional arguments passed on to the Form base - class __init__() - *form_kwargs: keyword arguments passed on to the Form base - class __init__() - """ - super(SelectQueryArgForm, self).__init__(*form_args, **form_kwargs) - - self._script = safestring.mark_safe(self.ONCHANGE_JAVASCRIPT_FMT % { - 'arg_name': arg_name, 'page_path': page_path,}) - - onchange_js_call = 'changeArg_%s(this)' % arg_name - - self.fields[field_name] = forms.ChoiceField( - label='', choices=choices, - widget=forms.widgets.Select(attrs={'onchange': onchange_js_call})) - - def as_table(self): - """Returns form rendered as HTML rows -- with no
. - - Prepends