[gen] Ref field: added params 'beforeLink' and 'afterUnlink' allowing to hold methods that execute respectively before an item is linked via a Ref or after it has been unlinked; bugfix in mixin::getUrl.
This commit is contained in:
parent
8511bcd675
commit
268309045a
|
@ -472,13 +472,14 @@ class Ref(Field):
|
||||||
def __init__(self, klass=None, attribute=None, validator=None,
|
def __init__(self, klass=None, attribute=None, validator=None,
|
||||||
multiplicity=(0,1), default=None, add=False, addConfirm=False,
|
multiplicity=(0,1), default=None, add=False, addConfirm=False,
|
||||||
delete=None, noForm=False, link=True, unlink=None, insert=None,
|
delete=None, noForm=False, link=True, unlink=None, insert=None,
|
||||||
back=None, show=True, page='main', group=None, layouts=None,
|
beforeLink=None, afterUnlink=None, back=None, show=True,
|
||||||
showHeaders=False, shownInfo=(), select=None, maxPerPage=30,
|
page='main', group=None, layouts=None, showHeaders=False,
|
||||||
move=0, indexed=False, searchable=False,
|
shownInfo=(), select=None, maxPerPage=30, move=0,
|
||||||
specificReadPermission=False, specificWritePermission=False,
|
indexed=False, searchable=False, specificReadPermission=False,
|
||||||
width=None, height=5, maxChars=None, colspan=1, master=None,
|
specificWritePermission=False, width=None, height=5,
|
||||||
masterValue=None, focus=False, historized=False, mapping=None,
|
maxChars=None, colspan=1, master=None, masterValue=None,
|
||||||
label=None, queryable=False, queryFields=None, queryNbCols=1,
|
focus=False, historized=False, mapping=None, label=None,
|
||||||
|
queryable=False, queryFields=None, queryNbCols=1,
|
||||||
navigable=False, changeOrder=True, numbered=False,
|
navigable=False, changeOrder=True, numbered=False,
|
||||||
checkboxes=True, checkboxesDefault=None, sdefault='',
|
checkboxes=True, checkboxesDefault=None, sdefault='',
|
||||||
scolspan=1, swidth=None, sheight=None, sselect=None,
|
scolspan=1, swidth=None, sheight=None, sselect=None,
|
||||||
|
@ -511,6 +512,10 @@ class Ref(Field):
|
||||||
self.link = link
|
self.link = link
|
||||||
# May the user unlink existing objects?
|
# May the user unlink existing objects?
|
||||||
self.unlink = unlink
|
self.unlink = unlink
|
||||||
|
if unlink == None:
|
||||||
|
# By default, one may unlink objects via a Ref for which one can
|
||||||
|
# link objects.
|
||||||
|
self.unlink = bool(self.link)
|
||||||
# When an object is inserted through this Ref field, at what position is
|
# When an object is inserted through this Ref field, at what position is
|
||||||
# it inserted? If "insert" is:
|
# it inserted? If "insert" is:
|
||||||
# None, it will be inserted at the end;
|
# None, it will be inserted at the end;
|
||||||
|
@ -529,10 +534,14 @@ class Ref(Field):
|
||||||
# object is inserted at some given place: tied objects are more
|
# object is inserted at some given place: tied objects are more
|
||||||
# maintained in the order of their insertion.
|
# maintained in the order of their insertion.
|
||||||
self.insert = insert
|
self.insert = insert
|
||||||
if unlink == None:
|
# Immediately before an object is going to be linked via this Ref field,
|
||||||
# By default, one may unlink objects via a Ref for which one can
|
# method specified in "beforeLink" wil be executed if specified and will
|
||||||
# link objects.
|
# take the object to link as single parameter.
|
||||||
self.unlink = bool(self.link)
|
self.beforeLink = beforeLink
|
||||||
|
# Immediately after an object as been unlinked from this Ref field,
|
||||||
|
# method specified in "afterUnlink" will be executed if specified and
|
||||||
|
# will take the unlinked object as single parameter.
|
||||||
|
self.afterUnlink = afterUnlink
|
||||||
self.back = None
|
self.back = None
|
||||||
if back:
|
if back:
|
||||||
# It is a forward reference
|
# It is a forward reference
|
||||||
|
@ -897,6 +906,8 @@ class Ref(Field):
|
||||||
# Insert p_value into it.
|
# Insert p_value into it.
|
||||||
uid = value.o.id
|
uid = value.o.id
|
||||||
if uid in refs: return
|
if uid in refs: return
|
||||||
|
# Execute self.beforeLink if present
|
||||||
|
if self.beforeLink: self.beforeLink(obj, value)
|
||||||
# Where must we insert the object?
|
# Where must we insert the object?
|
||||||
if not self.insert:
|
if not self.insert:
|
||||||
refs.append(uid)
|
refs.append(uid)
|
||||||
|
@ -945,6 +956,8 @@ class Ref(Field):
|
||||||
uid = value.o.id
|
uid = value.o.id
|
||||||
if uid in refs:
|
if uid in refs:
|
||||||
refs.remove(uid)
|
refs.remove(uid)
|
||||||
|
# Execute self.afterUnlink if present
|
||||||
|
if self.afterUnlink: self.afterUnlink(obj, value)
|
||||||
# Update the back reference
|
# Update the back reference
|
||||||
if not back: self.back.unlinkObject(value, obj, back=True)
|
if not back: self.back.unlinkObject(value, obj, back=True)
|
||||||
|
|
||||||
|
@ -1160,17 +1173,18 @@ class Ref(Field):
|
||||||
action = rq['linkAction']
|
action = rq['linkAction']
|
||||||
tool = obj.getTool()
|
tool = obj.getTool()
|
||||||
msg = None
|
msg = None
|
||||||
|
appyObj = obj.appy()
|
||||||
if not action.endswith('_many'):
|
if not action.endswith('_many'):
|
||||||
# "link" or "unlink"
|
# "link" or "unlink"
|
||||||
tied = tool.getObject(rq['targetUid'])
|
tied = tool.getObject(rq['targetUid'], appy=True)
|
||||||
exec 'self.%sObject(obj, tied, noSecurity=False)' % action
|
exec 'self.%sObject(appyObj, tied, noSecurity=False)' % action
|
||||||
else:
|
else:
|
||||||
# "link_many", "unlink_many", "delete_many". As a preamble, perform
|
# "link_many", "unlink_many", "delete_many". As a preamble, perform
|
||||||
# a security check once, instead of doing it on every object-level
|
# a security check once, instead of doing it on every object-level
|
||||||
# operation.
|
# operation.
|
||||||
obj.mayEdit(self.writePermission, raiseError=True)
|
obj.mayEdit(self.writePermission, raiseError=True)
|
||||||
# Get the (un-)checked objects from the request.
|
# Get the (un-)checked objects from the request.
|
||||||
uids = rq['targetUid'].strip(',') or ();
|
uids = rq['targetUid'].strip(',') or ()
|
||||||
if uids: uids = uids.split(',')
|
if uids: uids = uids.split(',')
|
||||||
unchecked = rq['semantics'] == 'unchecked'
|
unchecked = rq['semantics'] == 'unchecked'
|
||||||
if action == 'link_many':
|
if action == 'link_many':
|
||||||
|
@ -1192,7 +1206,8 @@ class Ref(Field):
|
||||||
# Keep only objects being in uids.
|
# Keep only objects being in uids.
|
||||||
if uid not in uids: continue
|
if uid not in uids: continue
|
||||||
# Collect this object
|
# Collect this object
|
||||||
target = not isObj and tool.getObject(value) or value.o
|
target = not isObj and tool.getObject(value, appy=True) or \
|
||||||
|
value
|
||||||
targets.append(target)
|
targets.append(target)
|
||||||
if not targets:
|
if not targets:
|
||||||
msg = obj.translate('action_null')
|
msg = obj.translate('action_null')
|
||||||
|
@ -1204,16 +1219,17 @@ class Ref(Field):
|
||||||
for target in targets:
|
for target in targets:
|
||||||
if mustDelete:
|
if mustDelete:
|
||||||
# Delete
|
# Delete
|
||||||
if target.mayDelete(): target.delete()
|
if target.o.mayDelete(): target.o.delete()
|
||||||
else: failed += 1
|
else: failed += 1
|
||||||
else:
|
else:
|
||||||
# Link or unlink
|
# Link or unlink
|
||||||
exec 'self.%sObject(obj, target)' % action.split('_')[0]
|
exec 'self.%sObject(appyObj, target)' % \
|
||||||
|
action.split('_')[0]
|
||||||
if failed:
|
if failed:
|
||||||
msg = obj.translate('action_partial', mapping={'nb':failed})
|
msg = obj.translate('action_partial', mapping={'nb':failed})
|
||||||
urlBack = obj.getUrl(rq['HTTP_REFERER'])
|
urlBack = obj.getUrl(rq['HTTP_REFERER'])
|
||||||
if not msg: msg = obj.translate('action_done')
|
if not msg: msg = obj.translate('action_done')
|
||||||
obj.say(msg)
|
appyObj.say(msg)
|
||||||
tool.goto(urlBack)
|
tool.goto(urlBack)
|
||||||
|
|
||||||
def autoref(klass, field):
|
def autoref(klass, field):
|
||||||
|
|
|
@ -1353,6 +1353,9 @@ class BaseMixin:
|
||||||
# Define base URL if omitted
|
# Define base URL if omitted
|
||||||
if not base:
|
if not base:
|
||||||
base = self.absolute_url() + suffix
|
base = self.absolute_url() + suffix
|
||||||
|
existingParams = ''
|
||||||
|
else:
|
||||||
|
existingParams = urllib.splitquery(base)[1]
|
||||||
# If a raw URL is asked, remove any param and suffix.
|
# If a raw URL is asked, remove any param and suffix.
|
||||||
if mode == 'raw':
|
if mode == 'raw':
|
||||||
if '?' in base: base = base[:base.index('?')]
|
if '?' in base: base = base[:base.index('?')]
|
||||||
|
@ -1366,7 +1369,6 @@ class BaseMixin:
|
||||||
if not kwargs: kwargs = self.getUrlDefaults
|
if not kwargs: kwargs = self.getUrlDefaults
|
||||||
if 'page' not in kwargs: kwargs['page'] = True
|
if 'page' not in kwargs: kwargs['page'] = True
|
||||||
if 'nav' not in kwargs: kwargs['nav'] = True
|
if 'nav' not in kwargs: kwargs['nav'] = True
|
||||||
kwargs['popup'] = inPopup and '1' or '0'
|
|
||||||
# Create URL parameters from kwargs
|
# Create URL parameters from kwargs
|
||||||
params = []
|
params = []
|
||||||
for name, value in kwargs.iteritems():
|
for name, value in kwargs.iteritems():
|
||||||
|
@ -1374,6 +1376,9 @@ class BaseMixin:
|
||||||
params.append('%s=%s' % (name, value))
|
params.append('%s=%s' % (name, value))
|
||||||
elif self.REQUEST.get(name, ''):
|
elif self.REQUEST.get(name, ''):
|
||||||
params.append('%s=%s' % (name, self.REQUEST[name]))
|
params.append('%s=%s' % (name, self.REQUEST[name]))
|
||||||
|
# Manage inPopup
|
||||||
|
if inPopup and ('popup=' not in existingParams):
|
||||||
|
params.append('popup=1')
|
||||||
if params:
|
if params:
|
||||||
params = '&'.join(params)
|
params = '&'.join(params)
|
||||||
if base.find('?') != -1: params = '&' + params
|
if base.find('?') != -1: params = '&' + params
|
||||||
|
|
Loading…
Reference in a new issue