0

I am trying to get data from a form, the form is reproduced a number of times based on a list. One form for each item. The form consists of a checkbox and a textfield. If the checkbox is checked then I need the accompanying textfield data as well.

I asked a related question here:

Django validation error u"'' value must be a decimal number."

Which was mostly solved however now I have a new issue.

view:

        for item in request.POST.getlist('item_list'):
            item_id = int(item)
            item = Item.objects.get(id=item_id)
            item_name = item.name
            print item_name


            list = List(name = item_name, created_on = now, edited_on = now)

            for price in request.POST.getlist('price'):
                                if not price:
                                    continue
                print price
                list_item.price = Decimal(price)
                list_item.save()
            item.delete()

Its not shown above but now = timezone.now().

template:

<form action="" method="post">

    {% csrf_token %}

    {% for item in item_list %}
        <input type="checkbox" name="item" value="{{item.id}}">{{item.name}} <input type="text" name="price"><br>
    {% endfor %}

    <input type="submit" value="Add Items">

</form>

When I submit the form it now runs through both loops twice and the final prices for all items are identical. I determined this by inserting print functions throughout my code and analyzing what is displayed. I guess I understand where the issue is, the question is how to correct it, any help would be greatly appreciated.

Community
  • 1
  • 1
apardes
  • 4,272
  • 7
  • 40
  • 66

1 Answers1

0

Your template repeats the following line many times:

<input type="checkbox" name="item" value="{{item.id}}">{{item.name}} <input type="text" name="price">

That creates a form with the fields item and price duplicated for every line. That is not a good way to create a form.

Instead, generate the lines with unique values for the name= attributes. For example,

<input type="checkbox" name="item_{{item.id}}">{{item.name}}
<input type="text" name="price_{{item.id}}">

Then back in your view, use this loop to find the matching pairs:

for key, value in request.POST.iteritems():
    if not name.startswith('item_'):
        continue
    name, item_id = key.split('_')
    if name == 'item':
        price = request.POST.get('price_%s' % item_id)
        # fetch the item, set the price
Brent Washburne
  • 12,904
  • 4
  • 60
  • 82
  • I don't fully understand what's happening here in the first line of your views.py code 'for key, value'. Specifically what key and value are. – apardes Aug 28 '13 at 23:51
  • That makes sense thanks. One last thing, why is it key.spit as opposed to value.split? – apardes Aug 29 '13 at 00:39
  • Unfortunately this did not work, it returns an error `need more than 1 value to unpack` at line `name, item_id = key.split('_')` – apardes Aug 29 '13 at 03:37
  • The `key` is the field `name`, and `value` is the field's value. The keys will be "item_#" or "price_#". If you have other fields in your form (that don't have a name with '_'), you'll see that error. I've added a line to the view to catch this case. – Brent Washburne Aug 29 '13 at 05:13