Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #2352 (closed enhancement: wontfix)

Opened 10 years ago

Last modified 10 years ago

Provide widget instance to callable default value

Reported by: xaka Owned by:
Priority: normal Milestone:
Component: TurboGears Version: 1.0.8
Severity: normal Keywords:
Cc:

Description

Good fix was provided in #1715 but not enough. I think that you should pass widget instance to callable object when calling. It makes possible return values depend on some attributes of widget (name or one of params). When you use callable object for default value it should be similar to instance method with "self" first argument.

Simple example:

def value_from_db(field):
  return get_value_from_db(field.name)

form = MyField(default=value_from_db)

Thanks.

Attachments

improve-callable-default.diff Download (2.0 KB) - added by xaka 10 years ago.

Change History

Changed 10 years ago by xaka

comment:1 Changed 10 years ago by chrisz

TG 1.0 is actually in feature freeze since many months; such things should go into 1.1.

But I'm not convinced that this feature should be included because it makes things more complicated. I'm all for keeping things simple and consistent - there are several other places (e.g. widget parameters) where we take callables, and they do not get parameters passed either. Neither does ToscaWidgets with which I'd like to stay compatible where possible.

Also, it's easy to achieve the same effect with a plain callable already. Here is an example where I pass the corresponding form widget instance (not the field instance which I think is less interesting):

class MyForm(widgets.TableForm):

    def mydefault(self):
        return "Bozo" # we could use self here

    fields = [widgets.TextField('name')]

myform=MyForm()

myform.fields[0].default = myform.mydefault

comment:2 Changed 10 years ago by Chris Arndt

I tend to agree with chrisz. -1 for including this.

comment:3 follow-up: ↓ 4 Changed 10 years ago by xaka

What you will do if you need return default value depend on field properties (name, params, something other)?

My patch backward-compatible, if your function/method doesn't expect any arguments - nothing wrong happens, in another case your first argument (or second for methods) will be instance of field.

comment:4 in reply to: ↑ 3 Changed 10 years ago by chrisz

Replying to xaka:

What you will do if you need return default value depend on field properties (name, params, something other)?

As explained above: Instead of return "Bozo" you could write something like return self.fields[0].name. The advantage here is that you can also refer to parameters of other fields that way. Or you can do the following if you only need parameters of the field itself:

class MyTextField(widgets.TextField):

    def default(self):
        return get_value_from_db(self.name)


class MyForm(widgets.TableForm):

    fields = [MyTextField(name='bozo')]

myform=MyForm()

Btw, do you want to use this trick to prepopulate the fields of a form with values from the database? This is much easier. You just pass the widget at render time the object from the database. No need to use default values for this. These come into play when you display a form to enter a new database record and are usually pretty static.

comment:5 Changed 10 years ago by Chris Arndt

  • Status changed from new to closed
  • Resolution set to wontfix

Look at partial functions in  http://docs.python.org/library/functools.html.

Note: See TracTickets for help on using tickets.