app/soc/views/helper/dynaform.py
author Sverre Rabbelier <srabbelier@gmail.com>
Sat, 29 Nov 2008 19:00:03 +0000
changeset 612 3cca81b1e5a1
parent 602 1caee6675fa7
child 629 492df53e4a0f
permissions -rw-r--r--
Moved checkAccess and getCleanedFields into access and forms A second patch in an effort to increase the cohesion in the base.View class. Patch by: Sverre Rabbelier
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
602
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
     1
#!/usr/bin/python2.5
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
     2
#
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
     3
# Copyright 2008 the Melange authors.
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
     4
#
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
     5
# Licensed under the Apache License, Version 2.0 (the "License");
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
     6
# you may not use this file except in compliance with the License.
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
     7
# You may obtain a copy of the License at
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
     8
#
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
     9
#   http://www.apache.org/licenses/LICENSE-2.0
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    10
#
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    11
# Unless required by applicable law or agreed to in writing, software
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    12
# distributed under the License is distributed on an "AS IS" BASIS,
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    13
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    14
# See the License for the specific language governing permissions and
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    15
# limitations under the License.
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    16
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    17
"""This module defines classes and functions for Dynamic Forms
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    18
"""
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    19
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    20
__authors__ = [
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    21
    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    22
    ]
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    23
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    24
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    25
from google.appengine.ext.db import djangoforms
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    26
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    27
from soc.logic import dicts
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    28
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    29
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    30
class DynaFormMetaclass(djangoforms.ModelFormMetaclass):
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    31
  """The DynaForm Meta class, adding support for dynamically defined fields
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    32
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    33
  The new DynaForm class that is created by class function is very
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    34
  similar to one created by the regular djangoforms.ModelFormMetaclass.
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    35
  The only difference is that is the form class has a Meta property,
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    36
  it's 'dynaconf' field will be used to define additional properties
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    37
  in the form class.
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    38
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    39
  The 'dynaconf' field (if present), is expected to be iterable as a
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    40
  dictionary (with iteritems). The keys are used as the property names,
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    41
  and the values are used as the property value.
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    42
  """
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    43
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    44
  def __new__(cls, class_name, bases, attrs):
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    45
    """See djangoforms.ModelFormMetaclass on how the __new__ method
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    46
    is used, for an explanation on how this class modifies the default
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    47
    behavior, see the DynaFormMetaclass's docstring.
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    48
    """
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    49
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    50
    # Retrieve the Meta class, if present
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    51
    meta = attrs.get('Meta', None)
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    52
    conf = None
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    53
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    54
    # Try to retrieve the dynaconf property
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    55
    if meta:
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    56
      conf = getattr(meta, 'dynaconf', None)
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    57
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    58
    # When found, extend the form's attribute's with the specified ones
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    59
    if conf:
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    60
      for key, value in conf.iteritems():
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    61
        attrs[key] = value
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    62
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    63
    # Leave the rest to djangoforms.ModelFormMetaclass.
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    64
    return super(DynaFormMetaclass, cls).__new__(cls, class_name, bases, attrs)
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    65
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    66
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    67
def newDynaForm(dynamodel=None, dynabase=None, dynainclude=None, 
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    68
                dynaexclude=None, dynafields=None):
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    69
  """Creates a new form DynaForm class
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    70
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    71
  The returned class extends dynabase, but with the following additions:
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    72
  * It has a Meta class with the 'model', 'include', and 'exclude'
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    73
  fields set as specified by newDynaForm's keyword arguments.
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    74
  * It's __metaclass__ is set to DynaFormMetaclass (which inherits from
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    75
  the default djangoforms.ModelFormMetaclass).
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    76
  * The Meta class has an additional dynaconf field which is set to
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    77
  the dyanfields keyword argument passed to newDynaForm.
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    78
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    79
  See DynaFormMetaclass for an explanation on how the dynafields
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    80
  property is used to construct the DynaForm class.
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    81
  """
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    82
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    83
  class DynaForm(dynabase):
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    84
    """The dynamically created Form class
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    85
    """
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    86
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    87
    __metaclass__ = DynaFormMetaclass
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    88
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    89
    class Meta:
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    90
      """Inner Meta class that defines some behavior for the form.
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    91
      """
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    92
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    93
      model = dynamodel
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    94
      include = dynainclude
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    95
      exclude = dynaexclude
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    96
      dynaconf = dynafields
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    97
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    98
  return DynaForm
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
    99
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   100
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   101
def extendDynaForm(dynaform, dynainclude=None, dynaexclude=None, dynafields=None):
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   102
  """Extends an existing dynaform
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   103
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   104
  If any of dynainclude, dynaexclude or dynafields are not present,
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   105
  they are retrieved from dynaform (if present in it's Meta class).
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   106
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   107
  While it is rather useles to extend from a dynaform that does not have
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   108
  a Meta class, it is allowed, the resulting DynaForm is the same as if
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   109
  newDynaForm was called with all extendDynForm's keyword arguments.
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   110
  """
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   111
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   112
  # Try to retrieve the Meta class from the existing dynaform
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   113
  meta = getattr(dynaform, 'Meta', None)
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   114
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   115
  # If we find one, we can use it to 'extend' from
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   116
  if meta:
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   117
    dynamodel = getattr(meta, 'model', None)
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   118
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   119
    if not dynainclude:
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   120
      dynainclude = getattr(meta, 'include', None)
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   121
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   122
    if not dynaexclude:
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   123
      dynaexclude = getattr(meta, 'exclude', None)
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   124
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   125
    # The most intersting parameter, the 'extra fields' dictionary
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   126
    dynaconf = getattr(meta, 'dynaconf', {})
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   127
    if not dynafields:
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   128
      dynafields = dynaconf
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   129
    else:
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   130
      dicts.merge(dynafields, dynaconf)
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   131
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   132
  # Create a new DynaForm, using the properties we extracted
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   133
  return newDynaForm(
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   134
      dynamodel=dynamodel,
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   135
      dynabase=dynaform,
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   136
      dynainclude=dynainclude,
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   137
      dynaexclude=dynaexclude,
1caee6675fa7 Added a DynaForm module
Sverre Rabbelier <srabbelier@gmail.com>
parents:
diff changeset
   138
      dynafields=dynafields)