From ea08d7981f7a8e5806fddbe34409d2ec446e4245 Mon Sep 17 00:00:00 2001 From: Gaetan Delannay Date: Tue, 4 Mar 2014 15:03:37 +0100 Subject: [PATCH] [gen] Added field.persist to avoid storing values for fields that do not require it (like master fields only used to determine selectable values among slave fields). --- fields/__init__.py | 33 ++++++++++++------------------- fields/action.py | 2 +- fields/boolean.py | 17 ++++++++-------- fields/calendar.py | 2 +- fields/computed.py | 2 +- fields/date.py | 5 +++-- fields/file.py | 2 +- fields/float.py | 4 ++-- fields/info.py | 2 +- fields/integer.py | 5 +++-- fields/list.py | 3 ++- fields/ogone.py | 2 +- fields/pod.py | 4 +++- fields/ref.py | 14 +++++++++---- fields/string.py | 10 ++++++---- gen/mixins/__init__.py | 26 ++++++++++++++++--------- gen/ui/appy.js | 39 +++++++++++++++++++++++++++---------- gen/wrappers/ToolWrapper.py | 7 ++++--- gen/wrappers/__init__.py | 2 +- 19 files changed, 106 insertions(+), 75 deletions(-) diff --git a/fields/__init__.py b/fields/__init__.py index 1013c35..2d6d386 100644 --- a/fields/__init__.py +++ b/fields/__init__.py @@ -61,8 +61,7 @@ class Field: value=zobj.getFormattedFieldValue(name, rawValue, showChanges); requestValue=zobj.getRequestFieldValue(name); inRequest=req.has_key(name); - errors=errors|(); - inError=name in errors; + error=req.get('%s_error' % name); isMultiple=(field.multiplicity[1] == None) or \ (field.multiplicity[1] > 1); masterCss=field.slaves and ('master_%s' % name) or ''; @@ -86,8 +85,8 @@ class Field: src=":url('help')"/>''') # Displays validation-error-related info about a field. - pxValidation = Px('''''') # Displays the fact that a field is required. @@ -107,7 +106,7 @@ class Field: layouts, move, indexed, searchable, specificReadPermission, specificWritePermission, width, height, maxChars, colspan, master, masterValue, focus, historized, sync, mapping, label, - sdefault, scolspan, swidth, sheight): + sdefault, scolspan, swidth, sheight, persist): # The validator restricts which values may be defined. It can be an # interval (1,None), a list of string values ['choice1', 'choice2'], # a regular expression, a custom function, a Selection instance, etc. @@ -215,6 +214,10 @@ class Field: # Width and height for the search widget self.swidth = swidth or width self.sheight = sheight or height + # "persist" indicates if field content must be stored in the database. + # For some fields it is not wanted (ie, fields used only as masters to + # update slave's selectable values). + self.persist = persist def init(self, name, klass, appName): '''When the application server starts, this secondary constructor is @@ -584,26 +587,14 @@ class Field: res += '+' return res - def getOnChange(self, name, zobj, layoutType): + def getOnChange(self, zobj, layoutType): '''When this field is a master, this method computes the call to the Javascript function that will be called when its value changes (in order to update slaves).''' if not self.slaves: return '' q = zobj.getTool().quote - # Create the dict of request values for slave fields. - rvs = {} - req = zobj.REQUEST - for slave in self.slaves: - name = slave.name - if not req.has_key(name): continue - if not req[name]: continue - rvs[name] = req[name] - if rvs: - rvs = ',%s' % sutils.getStringDict(rvs) - else: - rvs = '' - return 'updateSlaves(this,null,%s,%s%s)' % \ - (q(zobj.absolute_url()), q(layoutType), rvs) + return 'updateSlaves(this,null,%s,%s)' % \ + (q(zobj.absolute_url()), q(layoutType)) def isEmptyValue(self, value, obj=None): '''Returns True if the p_value must be considered as an empty value.''' @@ -680,7 +671,7 @@ class Field: def store(self, obj, value): '''Stores the p_value (produced by m_getStorableValue) that complies to p_self type definition on p_obj.''' - setattr(obj, self.name, value) + if self.persist: setattr(obj, self.name, value) def callMethod(self, obj, method, cache=True): '''This method is used to call a p_method on p_obj. p_method is part of diff --git a/fields/action.py b/fields/action.py index 1abf0ac..36ab937 100644 --- a/fields/action.py +++ b/fields/action.py @@ -74,7 +74,7 @@ class Action(Field): move, indexed, False, specificReadPermission, specificWritePermission, width, height, None, colspan, master, masterValue, focus, historized, False, mapping, - label, None, None, None, None) + label, None, None, None, None, False) self.validable = False def getDefaultLayouts(self): return {'view': 'l-f', 'edit': 'lrv-f'} diff --git a/fields/boolean.py b/fields/boolean.py index 0e2ca11..e283d96 100644 --- a/fields/boolean.py +++ b/fields/boolean.py @@ -23,19 +23,17 @@ from appy.gen.layout import Table class Boolean(Field): '''Field for storing boolean values.''' - pxView = pxCell = Px(''' - :value - - ''') + pxView = pxCell = Px(''':value + ''') pxEdit = Px(''' + q('%s_hidden' % name), \ + field.getOnChange(zobj, layoutType))"/> ''') @@ -64,13 +62,14 @@ class Boolean(Field): specificWritePermission=False, width=None, height=None, maxChars=None, colspan=1, master=None, masterValue=None, focus=False, historized=False, mapping=None, label=None, - sdefault=False, scolspan=1, swidth=None, sheight=None): + sdefault=False, scolspan=1, swidth=None, sheight=None, + persist=True): Field.__init__(self, validator, multiplicity, default, show, page, group, layouts, move, indexed, searchable, specificReadPermission, specificWritePermission, width, height, None, colspan, master, masterValue, focus, historized, True, mapping, label, sdefault, scolspan, - swidth, sheight) + swidth, sheight, persist) self.pythonType = bool # Layout including a description diff --git a/fields/calendar.py b/fields/calendar.py index c54c82c..f5b684e 100644 --- a/fields/calendar.py +++ b/fields/calendar.py @@ -222,7 +222,7 @@ class Calendar(Field): layouts, move, False, False, specificReadPermission, specificWritePermission, width, height, None, colspan, master, masterValue, focus, False, True, mapping, label, - None, None, None, None) + None, None, None, None, True) # eventTypes can be a "static" list or tuple of strings that identify # the types of events that are supported by this calendar. It can also # be a method that computes such a "dynamic" list or tuple. When diff --git a/fields/computed.py b/fields/computed.py index 1a64a1d..ea1a6b3 100644 --- a/fields/computed.py +++ b/fields/computed.py @@ -70,7 +70,7 @@ class Computed(Field): specificReadPermission, specificWritePermission, width, height, None, colspan, master, masterValue, focus, historized, sync, mapping, label, sdefault, scolspan, - swidth, sheight) + swidth, sheight, False) self.validable = False def getValue(self, obj): diff --git a/fields/date.py b/fields/date.py index 4f2416f..c266e93 100644 --- a/fields/date.py +++ b/fields/date.py @@ -173,7 +173,8 @@ class Date(Field): specificWritePermission=False, width=None, height=None, maxChars=None, colspan=1, master=None, masterValue=None, focus=False, historized=False, mapping=None, label=None, - sdefault=None, scolspan=1, swidth=None, sheight=None): + sdefault=None, scolspan=1, swidth=None, sheight=None, + persist=True): self.format = format self.calendar = calendar self.startYear = startYear @@ -186,7 +187,7 @@ class Date(Field): specificReadPermission, specificWritePermission, width, height, None, colspan, master, masterValue, focus, historized, True, mapping, label, sdefault, scolspan, - swidth, sheight) + swidth, sheight, persist) def getCss(self, layoutType, res): # CSS files are only required if the calendar must be shown. diff --git a/fields/file.py b/fields/file.py index 877ccff..fd0ba2c 100644 --- a/fields/file.py +++ b/fields/file.py @@ -279,7 +279,7 @@ class File(Field): specificReadPermission, specificWritePermission, width, height, None, colspan, master, masterValue, focus, historized, True, mapping, label, sdefault, scolspan, - swidth, sheight) + swidth, sheight, True) @staticmethod def getFileObject(filePath, fileName=None, zope=False): diff --git a/fields/float.py b/fields/float.py index 4ce633a..c0d69fe 100644 --- a/fields/float.py +++ b/fields/float.py @@ -58,7 +58,7 @@ class Float(Field): maxChars=13, colspan=1, master=None, masterValue=None, focus=False, historized=False, mapping=None, label=None, sdefault=('',''), scolspan=1, swidth=None, sheight=None, - precision=None, sep=(',', '.'), tsep=' '): + persist=True, precision=None, sep=(',', '.'), tsep=' '): # The precision is the number of decimal digits. This number is used # for rendering the float, but the internal float representation is not # rounded. @@ -80,7 +80,7 @@ class Float(Field): specificReadPermission, specificWritePermission, width, height, maxChars, colspan, master, masterValue, focus, historized, True, mapping, label, sdefault, scolspan, - swidth, sheight) + swidth, sheight, persist) self.pythonType = float def getFormattedValue(self, obj, value, showChanges=False): diff --git a/fields/info.py b/fields/info.py index 527d305..94a9e35 100644 --- a/fields/info.py +++ b/fields/info.py @@ -34,6 +34,6 @@ class Info(Field): move, indexed, False, specificReadPermission, specificWritePermission, width, height, None, colspan, master, masterValue, focus, historized, False, mapping, - label, None, None, None, None) + label, None, None, None, None, False) self.validable = False # ------------------------------------------------------------------------------ diff --git a/fields/integer.py b/fields/integer.py index 009fe40..76e8823 100644 --- a/fields/integer.py +++ b/fields/integer.py @@ -54,13 +54,14 @@ class Integer(Field): specificWritePermission=False, width=5, height=None, maxChars=13, colspan=1, master=None, masterValue=None, focus=False, historized=False, mapping=None, label=None, - sdefault=('',''), scolspan=1, swidth=None, sheight=None): + sdefault=('',''), scolspan=1, swidth=None, sheight=None, + persist=True): Field.__init__(self, validator, multiplicity, default, show, page, group, layouts, move, indexed, searchable, specificReadPermission, specificWritePermission, width, height, maxChars, colspan, master, masterValue, focus, historized, True, mapping, label, sdefault, scolspan, - swidth, sheight) + swidth, sheight, persist) self.pythonType = long def validateValue(self, obj, value): diff --git a/fields/list.py b/fields/list.py index e062e1f..b69e953 100644 --- a/fields/list.py +++ b/fields/list.py @@ -83,7 +83,8 @@ class List(Field): group, layouts, move, indexed, False, specificReadPermission, specificWritePermission, width, height, None, colspan, master, masterValue, focus, - historized, True, mapping, label, None, None, None, None) + historized, True, mapping, label, None, None, None, None, + True) self.validable = True # Tuples of (names, Field instances) determining the format of every # element in the list. diff --git a/fields/ogone.py b/fields/ogone.py index 269accc..3e69e84 100644 --- a/fields/ogone.py +++ b/fields/ogone.py @@ -54,7 +54,7 @@ class Ogone(Field): move, False, False,specificReadPermission, specificWritePermission, width, height, None, colspan, master, masterValue, focus, False, True, mapping, label, - None, None, None, None) + None, None, None, None, False) # orderMethod must contain a method returning a dict containing info # about the order. Following keys are mandatory: # * orderID An identifier for the order. Don't use the object UID diff --git a/fields/pod.py b/fields/pod.py index eba7c1c..41faed4 100644 --- a/fields/pod.py +++ b/fields/pod.py @@ -84,7 +84,9 @@ class Pod(Field): move, indexed, searchable, specificReadPermission, specificWritePermission, width, height, None, colspan, master, masterValue, focus, historized, False, mapping, - label, None, None, None, None) + label, None, None, None, None, True) + # Param "persist" is set to True but actually, persistence for a pod + # field is determined by freezing. self.validable = False def isFrozen(self, obj): diff --git a/fields/ref.py b/fields/ref.py index f6b1bfe..50d1858 100644 --- a/fields/ref.py +++ b/fields/ref.py @@ -286,7 +286,7 @@ class Ref(Field): uids=[o.UID() for o in \ field.getLinkedObjects(zobj).objects]" name=":name" id=":name" size=":isMultiple and field.height or ''" - onchange=":field.getOnChange(name, zobj, layoutType)" + onchange=":field.getOnChange(zobj, layoutType)" multiple=":isMultiple">