1
0
mirror of https://github.com/django/django.git synced 2025-06-05 03:29:12 +00:00

magic-removal: changed how child manipulators are stored in preparation for reordering and paging.

git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@1777 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Robert Wittams 2005-12-24 17:54:37 +00:00
parent 5c0fe75d44
commit 2466d9b0f1
4 changed files with 240 additions and 262 deletions

View File

@ -27,53 +27,45 @@ def add_stage(request, path, show_delete=False, form_url='', post_url='../', pos
new_data = request.POST.copy() new_data = request.POST.copy()
if opts.has_field_type(models.FileField): if opts.has_field_type(models.FileField):
new_data.update(request.FILES) new_data.update(request.FILES)
if request.POST.has_key("command"): #save a copy of the data to use for errors later.
#save a copy of the data to use for errors later. data = new_data.copy()
data = new_data.copy()
manipulator.do_html2python(new_data)
manipulator.do_html2python(new_data) #update the manipulator with the effects of previous commands.
manipulator.update(new_data)
#get the errors on the updated shape of the manipulator
#HACK - validators should not work on POSTED data directly...
errors = manipulator.get_validation_errors(data)
if request.POST.has_key("_preview"):
pass
elif request.POST.has_key("command"):
command_name = request.POST.get("command") command_name = request.POST.get("command")
manipulator.do_command(new_data, command_name) manipulator.do_command(command_name)
new_data = manipulator.flatten_data()
elif errors:
new_data = manipulator.flatten_data() new_data = manipulator.flatten_data()
#HACK - validators should not work on POSTED data directly...
errors = manipulator.get_validation_errors(data)
elif request.POST.has_key("_preview"):
errors = manipulator.get_validation_errors(new_data)
manipulator.do_html2python(new_data)
else: else:
#save a copy of the data to use for errors later. new_object = manipulator.save_from_update()
data = new_data.copy() log_add_message(request.user, opts, manipulator, new_object)
msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_object}
manipulator.do_html2python(new_data) pk_value = getattr(new_object, opts.pk.attname)
manipulator.update(new_data) # Here, we distinguish between different save types by checking for
errors = manipulator.get_validation_errors(data) # the presence of keys in request.POST.
if errors: if request.POST.has_key("_continue"):
data = manipulator.flatten_data() request.user.add_message(msg + ' ' + _("You may edit it again below."))
data.update(new_data)
new_data = data
else:
new_object = manipulator.save_from_update()
log_add_message(request.user, opts, manipulator, new_object)
msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_object}
pk_value = getattr(new_object, opts.pk.attname)
# Here, we distinguish between different save types by checking for
# the presence of keys in request.POST.
if request.POST.has_key("_continue"):
request.user.add_message(msg + ' ' + _("You may edit it again below."))
if request.POST.has_key("_popup"):
post_url_continue += "?_popup=1"
return HttpResponseRedirect(post_url_continue % pk_value)
if request.POST.has_key("_popup"): if request.POST.has_key("_popup"):
return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \ post_url_continue += "?_popup=1"
(pk_value, repr(new_object).replace('"', '\\"'))) return HttpResponseRedirect(post_url_continue % pk_value)
elif request.POST.has_key("_addanother"): if request.POST.has_key("_popup"):
request.user.add_message(msg + ' ' + (_("You may add another %s below.") % opts.verbose_name)) return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \
return HttpResponseRedirect(request.path) (pk_value, repr(new_object).replace('"', '\\"')))
else: elif request.POST.has_key("_addanother"):
request.user.add_message(msg) request.user.add_message(msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
return HttpResponseRedirect(post_url) return HttpResponseRedirect(request.path)
else:
request.user.add_message(msg)
return HttpResponseRedirect(post_url)
else: else:
# Add default data. # Add default data.
new_data = manipulator.flatten_data() new_data = manipulator.flatten_data()
@ -84,7 +76,7 @@ def add_stage(request, path, show_delete=False, form_url='', post_url='../', pos
errors = {} errors = {}
# Populate the FormWrapper. # Populate the FormWrapper.
form = formfields.FormWrapper(manipulator, new_data, errors, edit_inline=True) form = formfields.FormWrapper(manipulator, new_data, errors)
c = Context(request, { c = Context(request, {
'title': _('Add %s') % opts.verbose_name, 'title': _('Add %s') % opts.verbose_name,

View File

@ -46,59 +46,51 @@ def change_stage(request, path, object_id):
new_data = request.POST.copy() new_data = request.POST.copy()
if opts.has_field_type(models.FileField): if opts.has_field_type(models.FileField):
new_data.update(request.FILES) new_data.update(request.FILES)
if request.POST.has_key("command"): #save a copy of the data to use for errors later.
#save a copy of the data to use for errors later. data = new_data.copy()
data = new_data.copy()
manipulator.do_html2python(new_data)
manipulator.do_html2python(new_data) #update the manipulator with the effects of previous commands.
manipulator.update(new_data)
#get the errors on the updated shape of the manipulator
#HACK - validators should not work on POSTED data directly...
errors = manipulator.get_validation_errors(data)
if request.POST.has_key("_preview"):
pass
elif request.POST.has_key("command"):
command_name = request.POST.get("command") command_name = request.POST.get("command")
manipulator.do_command(new_data, command_name) manipulator.do_command(command_name)
new_data = manipulator.flatten_data()
elif errors:
new_data = manipulator.flatten_data() new_data = manipulator.flatten_data()
#HACK - validators should not work on POSTED data directly...
errors = manipulator.get_validation_errors(data)
elif request.POST.has_key("_preview"):
errors = manipulator.get_validation_errors(new_data)
manipulator.do_html2python(new_data)
else: else:
#save a copy of the data to use for errors later. new_object = manipulator.save_from_update()
data = new_data.copy() log_change_message(request.user, opts, manipulator, new_object)
msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object}
manipulator.do_html2python(new_data) pk_value = getattr(new_object, opts.pk.attname)
manipulator.update(new_data) if request.POST.has_key("_continue"):
errors = manipulator.get_validation_errors(data) request.user.add_message(msg + ' ' + _("You may edit it again below."))
if errors: if request.REQUEST.has_key('_popup'):
flat_data = manipulator.flatten_data() return HttpResponseRedirect(request.path + "?_popup=1")
flat_data.update(new_data)
new_data = flat_data
else:
new_object = manipulator.save_from_update()
log_change_message(request.user, opts, manipulator, new_object)
msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object}
pk_value = getattr(new_object, opts.pk.attname)
if request.POST.has_key("_continue"):
request.user.add_message(msg + ' ' + _("You may edit it again below."))
if request.REQUEST.has_key('_popup'):
return HttpResponseRedirect(request.path + "?_popup=1")
else:
return HttpResponseRedirect(request.path)
elif request.POST.has_key("_saveasnew"):
request.user.add_message(_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object})
return HttpResponseRedirect("../../%s/" % pk_value)
elif request.POST.has_key("_addanother"):
request.user.add_message(msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
return HttpResponseRedirect("../../add/")
else: else:
request.user.add_message(msg) return HttpResponseRedirect(request.path)
return HttpResponseRedirect("../../") elif request.POST.has_key("_saveasnew"):
request.user.add_message(_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object})
return HttpResponseRedirect("../../%s/" % pk_value)
elif request.POST.has_key("_addanother"):
request.user.add_message(msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
return HttpResponseRedirect("../../add/")
else:
request.user.add_message(msg)
return HttpResponseRedirect("../../")
else: else:
# Populate new_data with a "flattened" version of the current data. # Populate new_data with a "flattened" version of the current data.
new_data = manipulator.flatten_data() new_data = manipulator.flatten_data()
errors = {} errors = {}
# Populate the FormWrapper. # Populate the FormWrapper.
form = formfields.FormWrapper(manipulator, new_data, errors, edit_inline = True) form = formfields.FormWrapper(manipulator, new_data, errors)
form.original = manipulator.original_object form.original = manipulator.original_object
form.order_objects = [] form.order_objects = []

View File

@ -2,7 +2,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.core import formfields from django.core import formfields
from django.core.formfields import Manipulator from django.core.formfields import Manipulator
from django.db.models.fields import FileField, AutoField from django.db.models.fields import FileField, AutoField
from django.db.models.fields.related import ManyToOne
from django.db.models.exceptions import BadCommand from django.db.models.exceptions import BadCommand
from django.dispatch import dispatcher from django.dispatch import dispatcher
from django.db.models import signals from django.db.models import signals
@ -41,35 +41,6 @@ class ManipulatorDescriptor(object):
self.man._prepare(type) self.man._prepare(type)
return self.man return self.man
class ManipulatorHelper(object):
def __init__(self, manip, related, child_manipulators):
self.manip = manip
self.related = related
self.child_manipulators = child_manipulators
class FillHelper(ManipulatorHelper):
def matched_item(self,index, child_manip, obj_data):
child_manip._fill_data(obj_data)
def missing_item(self, index, child_manip):
child_manip.needs_deletion = True
def new_item(self, obj_data):
child_manip = self.manip._add_manipulator_for_child(self.related)
child_manip._fill_data(obj_data)
class SaveHelper(ManipulatorHelper):
def matched_item(self, index, child_manip, obj_data):
child_manip._save_expanded(obj_data)
def missing_item(self, index, child_manip):
child_manip.original_object.delete(ignore_objects=[parent.original_object])
def new_item(self, obj_data):
child_manip = self.manip._add_manipulator_for_child(self.related)
overrides = { self.related.field : self.manip.obj_key }
child_manip._save_expanded(obj_data, overrides)
class AutomaticManipulator(Manipulator): class AutomaticManipulator(Manipulator):
def _prepare(cls, model): def _prepare(cls, model):
cls.model = model cls.model = model
@ -122,7 +93,7 @@ class AutomaticManipulator(Manipulator):
fields = property(get_fields) fields = property(get_fields)
def get_original_value(self, field): def get_original_value(self, field):
raise NotImplementedError raise NotImplemented
def get_new_object(self, expanded_data, overrides=None): def get_new_object(self, expanded_data, overrides=None):
params = {} params = {}
@ -143,167 +114,110 @@ class AutomaticManipulator(Manipulator):
params[self.opts.pk.attname] = self.obj_key params[self.opts.pk.attname] = self.obj_key
return self.model(**params) return self.model(**params)
def _fill_related_objects(self, expanded_data, helper_factory):
for related, manips in self.children.items():
helper = helper_factory(self, related, manips)
child_data = MultiValueDict(expanded_data.get(related.var_name, MultiValueDict()) )
# existing objects
for index,manip in enumerate(manips):
obj_data = child_data.get(str(index), None)
child_data.pop(str(index), None)
if obj_data != None:
#the object has new data
helper.matched_item(index,manip, obj_data )
else:
#the object was not in the data
helper.missing_item(index,manip)
if child_data:
# There are new objects in the data
items = sorted(child_data.items(),cmp = lambda x, y: cmp(x[0], y[0]))
for index, obj_data in items:
helper.new_item(obj_data)
def _fill_data(self, expanded_data): def _fill_data(self, expanded_data):
if self.needs_deletion: if self.needs_deletion:
raise BadCommand, "Filling %s with %r when it needs deletion" % (self, expanded_data) raise BadCommand, "Filling %s with %r when it needs deletion" % (self, expanded_data)
self.original_object = self.get_new_object(expanded_data) self.original_object = self.get_new_object(expanded_data)
# TODO: many_to_many # TODO: many_to_many
self._fill_related_objects(expanded_data,FillHelper) for related, manips in self.children.items():
child_data = MultiValueDict(expanded_data.get(related.var_name, MultiValueDict()) )
manips._fill_data(child_data)
def update(self, new_data): def update(self, new_data):
expanded_data = dot_expand(new_data, MultiValueDict) expanded_data = dot_expand(new_data, MultiValueDict)
# Deal with the effects of previous commands # Deal with the effects of previous commands
self._fill_data(expanded_data) self._fill_data(expanded_data)
def save_from_update(self): def save_from_update(self, parent_key=None):
if self.needs_deletion: if self.needs_deletion:
if self.original_object != None: if self.original_object != None:
self.original_object.delete() self.original_object.delete()
return return
# TODO: many to many
self.original_object.save() self.original_object.save()
if not hasattr(self, 'obj_key'): if not hasattr(self, 'obj_key'):
self.obj_key = getattr(self.original_object, self.opts.pk.attname) self.obj_key = getattr(self.original_object, self.opts.pk.attname)
for related, manips in self.children.items(): for related, manips in self.children.items():
for i, manip in enumerate(manips): manips.save_from_update(self.obj_key)
setattr(manip.original_object, related.field.attname , self.obj_key)
manip.save_from_update()
return self.original_object return self.original_object
def do_command(self, new_data, command): def do_command(self, command):
expanded_data = dot_expand(new_data, MultiValueDict)
# Deal with the effects of previous commands
self._fill_data(expanded_data)
# Do this command # Do this command
command_parts = command.split('.') command_parts = command.split('.')
self._do_command_expanded(expanded_data, command_parts) self._do_command_expanded(command_parts)
def _do_command_expanded(self, expanded_data, command_parts): def _do_command_expanded(self, command_parts):
try: try:
part = command_parts.pop(0) part = command_parts.pop(0)
except IndexError: except IndexError:
raise BadCommand, "Not enough parts in command" raise BadCommand, "Not enough parts in command"
if part == "delete":
# must be the name of a child manipulator collection self.needs_deletion = True
child_manips = None else:
related = None # must be the name of a child manipulator collection
for rel,manips in self.children.items(): child_manips = None
if rel.var_name == part: for rel,manips in self.children.items():
related = rel if rel.var_name == part:
child_manips = manips child_manips = manips
break break
if child_manips == None: if child_manips == None:
raise BadCommand, "'%s' : unknown manipulator collection name." % (part,) raise BadCommand, "'%s' : unknown manipulator collection name." % (part,)
child_data = expanded_data.get(part, MultiValueDict())
# The next part could be an index of a manipulator,
# or it could be a command on the collection.
try:
index_part = command_parts.pop(0)
except IndexError:
raise BadCommand, "Not enough parts in command"
try:
index = int(index_part)
manip = child_manips[index]
if manip == None:
raise BadCommand, "No %s manipulator found for index %s in command." % (part, index)
obj_data = child_data.get(index_part, None)
if obj_data == None:
raise BadCommand, "Could not find data for manipulator %s in %s collection." % (index, part)
if command_parts == ["delete"]:
child_manips[index] = None
else: else:
manip._do_command_expanded(obj_data,command_parts) child_manips._do_command_expanded(command_parts)
except ValueError:
# Must be a command on the collection. Possible commands:
# add.
if index_part == "add":
self._add_manipulator_for_child(related)
else:
raise BadCommand, "%s, unknown command" % (part)
def _add_manipulator_for_child(self, related):
child_manips = self.children.setdefault(related, [])
fol = self.follow[related.name]
prefix = "%s%s.%s." % (self.name_prefix, related.var_name, len(child_manips) )
child_manip = related.model.AddManipulator(follow=fol,name_prefix=prefix)
child_manips.append(child_manip)
return child_manip
def save(self, new_data): def save(self, new_data):
expanded_data = dot_expand(new_data,MultiValueDict) self.update(new_data)
return self._save_expanded(expanded_data) self.save_from_update()
def _save_expanded(self, expanded_data, overrides = None): # def _save_expanded(self, expanded_data, overrides = None):
add, change, opts, klass = self.add, self.change, self.opts, self.model # add, change, opts, klass = self.add, self.change, self.opts, self.model
#
new_object = self.get_new_object(expanded_data, overrides) # new_object = self.get_new_object(expanded_data, overrides)
#
# First, save the basic object itself. # # First, save the basic object itself.
new_object.save() # new_object.save()
#
# Save the key for use in creating new related objects. # # Save the key for use in creating new related objects.
if not hasattr(self, 'obj_key'): # if not hasattr(self, 'obj_key'):
self.obj_key = getattr(new_object, self.opts.pk.attname) # self.obj_key = getattr(new_object, self.opts.pk.attname)
#
# Now that the object's been saved, save any uploaded files. # # Now that the object's been saved, save any uploaded files.
for f in opts.fields: # for f in opts.fields:
if isinstance(f, FileField): # if isinstance(f, FileField):
f.save_file(new_data, new_object, change and self.original_object or None, change) # f.save_file(new_data, new_object, change and self.original_object or None, change)
#
# Calculate which primary fields have changed. # # Calculate which primary fields have changed.
#
#
# for f in opts.fields: # # for f in opts.fields:
# if not f.primary_key and str(getattr(self.original_object, f.attname)) != str(getattr(new_object, f.attname)): # # if not f.primary_key and str(getattr(self.original_object, f.attname)) != str(getattr(new_object, f.attname)):
# self.fields_changed.append(f.verbose_name) # # self.fields_changed.append(f.verbose_name)
#
# Save many-to-many objects. Example: Poll.set_sites() # # Save many-to-many objects. Example: Poll.set_sites()
for f in opts.many_to_many: # for f in opts.many_to_many:
if self.follow.get(f.name, None): # if self.follow.get(f.name, None):
if not f.rel.edit_inline: # if not f.rel.edit_inline:
if f.rel.raw_id_admin: # if f.rel.raw_id_admin:
new_vals = new_data.get(f.name, ()) # new_vals = new_data.get(f.name, ())
else: # else:
new_vals = new_data.getlist(f.name) # new_vals = new_data.getlist(f.name)
was_changed = getattr(new_object, 'set_%s' % f.name)(new_vals) # was_changed = getattr(new_object, 'set_%s' % f.name)(new_vals)
if change and was_changed: # if change and was_changed:
self.fields_changed.append(f.verbose_name) # self.fields_changed.append(f.verbose_name)
#
# Save inline edited objects # # Save inline edited objects
self._fill_related_objects(expanded_data,SaveHelper) # self._fill_related_objects(expanded_data,SaveHelper)
#
return new_object # return new_object
#
# Save the order, if applicable. # # Save the order, if applicable.
#if change and opts.get_ordered_objects(): # #if change and opts.get_ordered_objects():
# order = new_data['order_'] and map(int, new_data['order_'].split(',')) or [] # # order = new_data['order_'] and map(int, new_data['order_'].split(',')) or []
# for rel_opts in opts.get_ordered_objects(): # # for rel_opts in opts.get_ordered_objects():
# getattr(new_object, 'set_%s_order' % rel_opts.object_name.lower())(order) # # getattr(new_object, 'set_%s_order' % rel_opts.object_name.lower())(order)
def get_related_objects(self): def get_related_objects(self):
@ -334,7 +248,7 @@ class ModelAddManipulator(AutomaticManipulator):
return field.get_default() return field.get_default()
def __repr__(self): def __repr__(self):
return "<Automatic AddManipulator for %s>" % (self.model) return "<Automatic AddManipulator '%s' for %s>" % (self.name_prefix, self.model.__name__, )
class ModelChangeManipulator(AutomaticManipulator): class ModelChangeManipulator(AutomaticManipulator):
change = True change = True
@ -380,9 +294,96 @@ class ModelChangeManipulator(AutomaticManipulator):
return getattr(self.original_object, field.attname) return getattr(self.original_object, field.attname)
def __repr__(self): def __repr__(self):
return "<Automatic ChangeManipulator for %s:%r >" % (self.model, self.obj_key) return "<Automatic ChangeManipulator '%s' for %s:%r >" % (self.name_prefix, self.model.__name__, self.obj_key)
class ManipulatorCollection(list):
def __init__(self,related, parent_prefix, instance, follow):
self.related = related
self.name_prefix = '%s%s.' % ( parent_prefix, related.var_name)
self.follow = follow
self._load(instance)
def _load(self, instance):
man_class = self.related.model.ChangeManipulator
if instance != None:
meth_name = 'get_%s_list' % self.related.get_method_name_part()
list = getattr(instance, meth_name)()
else:
list = []
for i,obj in enumerate(list):
prefix = '%s%d.' % (self.name_prefix, i)
self.append(man_class(obj,self.follow, prefix) )
def save_from_update(self, parent_key):
for manip in self:
if manip:
setattr(manip.original_object, self.related.field.attname , parent_key)
manip.save_from_update()
def _fill_data(self, expanded_data):
for index,manip in enumerate(self):
obj_data = expanded_data.get(str(index), None)
expanded_data.pop(str(index), None)
if manip:
if obj_data != None:
#the object has new data
manip._fill_data(obj_data)
else:
#the object was not in the data
manip.needs_deletion = True
if expanded_data:
# There are new objects in the data
items = [ (int(k),v ) for k,v in expanded_data.items() ]
items.sort(cmp = lambda x, y: cmp(x[0], y[0]))
for index, obj_data in items:
child_manip = self.add_child(index)
child_manip._fill_data(obj_data)
def _do_command_expanded(self, command_parts):
# The next part could be an index of a manipulator,
# or it could be a command on the collection.
try:
index_part = command_parts.pop(0)
except IndexError:
raise BadCommand, "Not enough parts in command"
try:
index = int(index_part)
try:
manip = self[index]
except IndexError:
raise BadCommand, "No %s manipulator found for index %s in command." % (part, index)
if manip == None:
raise BadCommand, "No %s manipulator found for index %s in command." % (part, index)
manip._do_command_expanded(command_parts)
except ValueError:
# Must be a command on the collection. Possible commands:
# add.
# TODO: page.forward, page.back, page.n, swap.n.m
if index_part == "add":
self.add_child()
else:
raise BadCommand, "%s, unknown command" % (part)
def add_child(self, index = None):
man_class = self.related.model.AddManipulator
if index == None:
index = len(self)
# Make sure that we are going to put this in the right index, by prefilling with Nones.
for i in range(len(self), index + 1):
self.append(None)
prefix = '%s%s.' % (self.name_prefix, index )
child_manip = man_class(self.follow, prefix)
self[index] = child_manip
return child_manip
def manipulator_validator_unique_together(field_name_list, opts, self, field_data, all_data): def manipulator_validator_unique_together(field_name_list, opts, self, field_data, all_data):
from django.db.models.fields.related import ManyToOne
from django.utils.text import get_text_list from django.utils.text import get_text_list
field_list = [opts.get_field(field_name) for field_name in field_name_list] field_list = [opts.get_field(field_name) for field_name in field_name_list]
if isinstance(field_list[0].rel, ManyToOne): if isinstance(field_list[0].rel, ManyToOne):
@ -414,6 +415,7 @@ def manipulator_validator_unique_together(field_name_list, opts, self, field_dat
{'object': capfirst(opts.verbose_name), 'type': field_list[0].verbose_name, 'field': get_text_list(field_name_list[1:], 'and')} {'object': capfirst(opts.verbose_name), 'type': field_list[0].verbose_name, 'field': get_text_list(field_name_list[1:], 'and')}
def manipulator_validator_unique_for_date(from_field, date_field, opts, lookup_type, self, field_data, all_data): def manipulator_validator_unique_for_date(from_field, date_field, opts, lookup_type, self, field_data, all_data):
from django.db.models.fields.related import ManyToOne
date_str = all_data.get(date_field.get_manipulator_field_names('')[0], None) date_str = all_data.get(date_field.get_manipulator_field_names('')[0], None)
date_val = formfields.DateField.html2python(date_str) date_val = formfields.DateField.html2python(date_str)
if date_val is None: if date_val is None:

View File

@ -1,3 +1,5 @@
from django.db.models.manipulators import ManipulatorCollection
class BoundRelatedObject(object): class BoundRelatedObject(object):
def __init__(self, related_object, field_mapping, original): def __init__(self, related_object, field_mapping, original):
self.relation = related_object self.relation = related_object
@ -78,20 +80,10 @@ class RelatedObject(object):
return ([], self.get_manipulators(manipulator, follow) ) return ([], self.get_manipulators(manipulator, follow) )
def get_manipulators(self,parent_manipulator, follow): def get_manipulators(self,parent_manipulator, follow):
name_prefix = parent_manipulator.name_prefix
obj = parent_manipulator.original_object
man_class = self.model.ChangeManipulator return ManipulatorCollection(self, name_prefix, obj, follow)
if parent_manipulator.original_object:
meth_name = 'get_%s_list' % self.get_method_name_part()
list = getattr(parent_manipulator.original_object, meth_name)()
else:
list = []
manipulators = []
for i,obj in enumerate(list):
prefix = '%s%s.%d.' % (parent_manipulator.name_prefix, self.var_name, i)
manipulators.append(man_class(obj,follow, prefix) )
return manipulators
def bind(self, field_mapping, original, bound_related_object_class=BoundRelatedObject): def bind(self, field_mapping, original, bound_related_object_class=BoundRelatedObject):
return bound_related_object_class(self, field_mapping, original) return bound_related_object_class(self, field_mapping, original)