how do I dynamically modify a choice field

1,141 views
Skip to first unread message

frocco

unread,
Jan 23, 2013, 3:36:46 PM1/23/13
to django...@googlegroups.com
Hello,

In my view, I am displaying rows of data that have a choice field in a form.
one form for each row

I want to change the choice this before printing.

one row can have 1 to 5 choices
another row can have 1 to 10 choices depending on values in each row.

Mike Dewhirst

unread,
Jan 23, 2013, 11:03:28 PM1/23/13
to django...@googlegroups.com
I'm likely to want something similar soon so I googled "how do I
dynamically modify a django choice field" and got at least a page of
results. Here is one which I looked at and found interesting. It may
suit your needs ...

http://ilian.i-n-i.org/django-forms-choicefield-with-dynamic-values/

Good luck

Mike

>
> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/django-users/-/BSrfbUYb_v8J.
> To post to this group, send email to django...@googlegroups.com.
> To unsubscribe from this group, send email to
> django-users...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/django-users?hl=en.

frocco

unread,
Jan 23, 2013, 11:46:17 PM1/23/13
to django...@googlegroups.com
Thanks Mike,

I do not know if this will work.
I want to change the field in the template as I read each row.
I do this in PHP rather easy, but am confused on how to do this using django.

Mike Dewhirst

unread,
Jan 24, 2013, 5:41:03 AM1/24/13
to django...@googlegroups.com
On 24/01/2013 10:46am, frocco wrote:
> Thanks Mike,
>
> I do not know if this will work.
> I want to change the field in the template as I read each row.
> I do this in PHP rather easy, but am confused on how to do this using
> django.

I haven't done much php (only emergency repairs to stuff written by
others after they have disappeared!) so I don't know how easy that might be.

In Django templates you can use HTML and for-loops to do most things.
You just write a class in your view to get the data from a query_set and
construct a list of objects (in your case, each row and a list of all of
its individual choices as found - foreign key or many-to-many - in the
database) and render it in your template. There is plenty of template
power available ...

https://docs.djangoproject.com/en/1.4/ref/templates/builtins/

It might look like this ...

{% if list_of_row_objects %}
<ul>
{% for row_object in list_of_row_objects %}
<li>{{ row_object.field_name }}
<p>There are {{ row_object.choices|length }} choices
<ol>
{% for choice in row_object.choices %}
<li>{{ choice.name }}</li>
{% empty %}
<li>There are no choices for this row</li>
{% endfor %}
</ol>
</li>
{% endfor %}
</ul>
{% else %}
<p>Sorry, no list of row objects today!</p>
{% endif %}

hth

Mike


>
>
> On Wednesday, January 23, 2013 6:03:28 PM UTC-5, Mike Dewhirst wrote:
>
> On 24/01/2013 2:36am, frocco wrote:
> > Hello,
> >
> > In my view, I am displaying rows of data that have a choice field
> in a form.
> > one form for each row
> >
> > I want to change the choice this before printing.
> >
> > one row can have 1 to 5 choices
> > another row can have 1 to 10 choices depending on values in each
> row.
>
> I'm likely to want something similar soon so I googled "how do I
> dynamically modify a django choice field" and got at least a page of
> results. Here is one which I looked at and found interesting. It may
> suit your needs ...
>
> http://ilian.i-n-i.org/django-forms-choicefield-with-dynamic-values/
> <http://ilian.i-n-i.org/django-forms-choicefield-with-dynamic-values/>
>
> Good luck
>
> Mike
>
> >
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Django users" group.
> > To view this discussion on the web visit
> > https://groups.google.com/d/msg/django-users/-/BSrfbUYb_v8J
> <https://groups.google.com/d/msg/django-users/-/BSrfbUYb_v8J>.
> > To post to this group, send email to django...@googlegroups.com
> <javascript:>.
> > To unsubscribe from this group, send email to
> > django-users...@googlegroups.com <javascript:>.
> > For more options, visit this group at
> > http://groups.google.com/group/django-users?hl=en
> <http://groups.google.com/group/django-users?hl=en>.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/django-users/-/rP_BPdN3JHgJ.

frocco

unread,
Jan 24, 2013, 11:30:20 AM1/24/13
to django...@googlegroups.com
Thanks Mike,

Since  I am new to django, how would I code this?

In my for loop, my row.stock field has a value.
Lets say row.stock is 20
I want my choice field to show 1 to 20

The next row.stock might have 12
I want my choice field to show 1 to 12

In other words, I do not want the user to select more stock than is available.

Thanks again for your help.

Mike Dewhirst

unread,
Jan 24, 2013, 12:06:41 PM1/24/13
to django...@googlegroups.com
On 24/01/2013 10:30pm, frocco wrote:
> Thanks Mike,
>
> Since I am new to django, how would I code this?
>
> In my for loop, my row.stock field has a value.
> Lets say row.stock is 20
> I want my choice field to show 1 to 20
>
> The next row.stock might have 12
> I want my choice field to show 1 to 12
>
> In other words, I do not want the user to select more stock than is
> available.

That would be easy enough (look up range in the Python docs) but I'm not
sure what you want to do is a good idea.

What happens if you present a range from 1 to 12 and while the user is
thinking about it someone else buys half a dozen?

Personally, I would be assuming orders will be un-satisfied and
re-design to cater for that gracefully. Perhaps you really need a
back-ordering system?

Mike


>
> Thanks again for your help.
>
>
> On Wednesday, January 23, 2013 10:36:46 AM UTC-5, frocco wrote:
>
> Hello,
>
> In my view, I am displaying rows of data that have a choice field in
> a form.
> one form for each row
>
> I want to change the choice this before printing.
>
> one row can have 1 to 5 choices
> another row can have 1 to 10 choices depending on values in each row.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/django-users/-/YTrTuwNU0zwJ.

frocco

unread,
Jan 24, 2013, 1:14:46 PM1/24/13
to django...@googlegroups.com
I see your point.
maybe I should validate stock when they press update and/or post order.


On Wednesday, January 23, 2013 10:36:46 AM UTC-5, frocco wrote:

Bill Freeman

unread,
Jan 24, 2013, 1:31:46 PM1/24/13
to django...@googlegroups.com
On Thu, Jan 24, 2013 at 7:06 AM, Mike Dewhirst <mi...@dewhirst.com.au> wrote:
On 24/01/2013 10:30pm, frocco wrote:
Thanks Mike,

Since  I am new to django, how would I code this?

In my for loop, my row.stock field has a value.
Lets say row.stock is 20
I want my choice field to show 1 to 20

The next row.stock might have 12
I want my choice field to show 1 to 12

In other words, I do not want the user to select more stock than is
available.

That would be easy enough (look up range in the Python docs) but I'm not sure what you want to do is a good idea.

What happens if you present a range from 1 to 12 and while the user is thinking about it someone else buys half a dozen?

Personally, I would be assuming orders will be un-satisfied and re-design to cater for that gracefully. Perhaps you really need a back-ordering system?

Certainly you must have a strategy for dealing with the potential for the limit having changed since the form was displayed, but the use case is still reasonable.

I don't believe that the ability to provide a coded iterable object as the value of choices is going to help, since I don't believe that there is a way for it to access the instance of the model (from which to find the current in stock number).

You could add a method to your class that returns range(1, 1 + self.stock) and use that to control a template "for" tag building your list of html option tags for a select drop down.  (range is a python builtin, in case you're not familiar with it.)  The problem that I see here is that if row.stock is large, you probably don't want to use a drop down, since it doesn't have comfortable usability for the visitor.  You could switch to just providing a text input if the stock is too large, along with a note saying what the limit is.

If you do a text input, you would probably like to validate it before submission (although you will certainly want to validate it in the view as well).  When the new input tag attributes of HTML5 become universal, that will be straightforward.  But pre-submission validation today requires JavaScript.  Even I tend to enable the site's javascript when I'm ordering something on line, so that's a pretty safe bet today.  But if you can count on javascript, you can build the select option list and/or validate the text input using javascript as well, if you render a hidden or non-editable input initialized to row.stock.  Note that the hidden field gets submitted, so the back end validation can tell whether the available number changed between GET and POST, or whether a non-javascript or firebug using user has entered a number larger than you said was available, just in case you want to provide different error messages for these two cases.

Bill
Reply all
Reply to author
Forward
0 new messages