Proposal - ChoiceField.choices need to accept callable, not only list or tuple

92 views
Skip to first unread message

George Karpenkov

unread,
Mar 23, 2010, 1:30:38 AM3/23/10
to Django developers, ad...@metaworld.ru
Hi,

The subject pretty much describes all of it. If 'initial' can be a
callable, why 'choices' can't? Writing custom function is way more
convenient then altering __init__ method of the model.

I'm happy to write up a patch if it would be likely to be accepted

Jared Forsyth

unread,
Mar 23, 2010, 1:42:37 AM3/23/10
to django-d...@googlegroups.com, ad...@metaworld.ru
I say go for it, and post again with a patch and issue number (once you've created them). Your idea seems sound.

Jared


--
You received this message because you are subscribed to the Google Groups "Django developers" group.
To post to this group, send email to django-d...@googlegroups.com.
To unsubscribe from this group, send email to django-develop...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.


George Karpenkov

unread,
Mar 23, 2010, 2:25:25 AM3/23/10
to Django developers
http://code.djangoproject.com/ticket/13181

On Mar 23, 4:42 pm, Jared Forsyth <jabap...@gmail.com> wrote:
> I say go for it, and post again with a patch and issue number (once you've
> created them). Your idea seems sound.
>
> Jared
>
> On Mon, Mar 22, 2010 at 11:30 PM, George Karpenkov

> <true.chesh...@gmail.com>wrote:


>
>
>
> > Hi,
>
> > The subject pretty much describes all of it. If 'initial' can be a
> > callable, why 'choices' can't? Writing custom function is way more
> > convenient then altering __init__ method of the model.
>
> > I'm happy to write up a patch if it would be likely to be accepted
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Django developers" group.
> > To post to this group, send email to django-d...@googlegroups.com.
> > To unsubscribe from this group, send email to

> > django-develop...@googlegroups.com<django-developers%2Bunsubscr i...@googlegroups.com>

Ivan Sagalaev

unread,
Mar 23, 2010, 8:20:13 PM3/23/10
to django-d...@googlegroups.com
George Karpenkov wrote:
> http://code.djangoproject.com/ticket/13181

I'm -1 on complicating it this way. The ability to pass a callable for
choices is covered by passing a generator. Am I missing something?

George Karpenkov

unread,
Mar 23, 2010, 9:56:57 PM3/23/10
to Django developers
Hi Ivan,

Given your experience, the chances are that you're right, however, I
don't see any way how we can pass a generator which will not be called
until the form class is instantiated.

We can't pass a generator function to choices (list() call will fail);
we can pass the generator expression but
a) the first call to it will be done before the class instantiation
b) it can be way more convenient to pass a function then a generator
expression (generator expression can be very hard to code if it has to
contain some complex logic)

Ivan Sagalaev

unread,
Mar 24, 2010, 2:48:16 AM3/24/10
to django-d...@googlegroups.com
George Karpenkov wrote:
> Given your experience, the chances are that you're right, however, I
> don't see any way how we can pass a generator which will not be called
> until the form class is instantiated.

Why should a call matter? The body of the generator is not executed
until first iteration attempt and can contain whatever lazy logic you need.

Can you provide an example where you need a function returning a list
and generator wouldn't suffice.

> b) it can be way more convenient to pass a function then a generator
> expression (generator expression can be very hard to code if it has to
> contain some complex logic)

I fail to see the difference here. A function that builds and returns a
list is trivially converted into generator by replacing ".append(...)"
with "yield ..." or replacing a list comprehension with a generator
expression.

Luca Sbardella

unread,
Mar 24, 2010, 3:29:06 AM3/24/10
to django-d...@googlegroups.com
Hi there,
I've used a different approach to solve the problem.
If of interest, here is the snippet
for solving the the problem of a run-time ChoiceField.
The choices argument is a generator (or the usual list of tuples).


--
You received this message because you are subscribed to the Google Groups "Django developers" group.
To post to this group, send email to django-d...@googlegroups.com.
To unsubscribe from this group, send email to django-develop...@googlegroups.com.

George Karpenkov

unread,
Mar 24, 2010, 6:21:07 AM3/24/10
to Django developers
oh wait, you're right.
(though choices=my_func seems to be neater then choices=(c for c in
my_func())

(for some reason i thought that choices=(c for c in my_func()) will
evaluate the my_func before we'll iterate through choices, but it
won't)

Vladimir Sidorenko

unread,
Mar 24, 2010, 7:21:08 AM3/24/10
to django-d...@googlegroups.com
Hi

George, as far as I remember, ChoiceField has a line like:
self.choices = list(choices)
in __init__ method.

Until this is changed, there is no difference in passing a callable, a list, or a generator.

So what do you suggest:
To simply allow passing a callable, or to allow truly dynamic choices, that are evaluated many times?

24 марта 2010, в 12:21, George Karpenkov написал(а):

> oh wait, you're right.
> (though choices=my_func seems to be neater then choices=(c for c in
> my_func())
>
> (for some reason i thought that choices=(c for c in my_func()) will
> evaluate the my_func before we'll iterate through choices, but it
> won't)

--
Vladimir Sidorenko
skype: v.sidorenko

Reply all
Reply to author
Forward
0 new messages