how to name numerous dynamic input fields for post method - Django

时光怂恿深爱的人放手 提交于 2021-02-05 10:38:03

问题


In my online shop, I fetch all of the products and services from two different apps and list them for the user to make his wishlist.

Each product or service is displayed in a bootstrap card that contains an input field for the count of products.

#views.py
def my_products(request):
    
    ip_sensor = Ip_sensor.objects.all().order_by('title')
    control_valves = ControlValves.objects.all().order_by('title')

    context = {
        'ip_sensor': ip_sensor,
        'control_valves': control_valves,        
    }
    return render(request, 'users/basket/my_products.html', context)

then in the template, they are being displayed in this way:

<form method="post" id="add_to_wishlist" data-url="{% url 'my_products' %}">
{% csrf_token %}

{% if ip_sensor %}
{% for item in ip_sensor %}

    <div class="card">

      <div class="card-body">

        <div class="row">

          <div class="col-12">
            <p class="card-text text-center text-capitalize">{{ item.title }}</p>
          </div>

          <div class="col-12">
            <div class="form-group">
              <input type="hidden" name="tag" value="{{ item.type }}">  <!-- what to put in name field of this line -->         
              <input type="hidden" name="item_id" value="{{ item.id }}">   <!-- what to put in name field of this line -->         
              <label for="count" class="control-label">count</label>     
              <input  type="text"    
                      id="count" 
                      name="count"             <!-- what to put in name field of this line -->         
                      placeholder="Count" 
                      class="form-control"
                      autofocus/> 
            </div>
          </div>

        </div>
        
      </div>
    </div>

{% endfor %}
{% endif %}

</form>

Question:

When I return the count of each product or service through a POST method back to my views.py to save to his wishlist, I don't know how to distinguish between the returned values??

Since items are being displayed in a for loop and I want to save each of the selected items separately in a WishListItem object (model), I need to name each card's input fields separately but I don't know how to do it.

I can save each item in this way:

if request.method == 'POST':
    owner = request.user

    count = request.POST.get('count')
    tag = request.POST.get('tag') 
    object_id = request.POST.get('item_id')
    
    wishlist = WishListItem(owner=owner,
                            content_type=class_types[tag],
                            object_id=object_id,
                            tag=tag,
                            count=count)
    wishlist.save()
    
    return redirect('my_products')

回答1:


When there are multiple inputs with same name, request.POST has list of all those input element values. So, you can get all item ids using request.POST.getlist('item_id') and it will return list containing all ids. In your html you can name all other inputs using id as part of the name attribute, like this:

...
<input type="hidden" name="tag_{{ item.id }}" value="{{ item.type }}">  <!-- item id has become part of the input name -->         
<input type="hidden" name="item_id" value="{{ item.id }}">   <!-- all item ids will be accessed as list in view -->         
<label for="count" class="control-label">count</label>     
<input  type="text"    
                      id="count" 
                      name="count_{{ item.id }}" <!-- item id has become part of the input name -->         
                      placeholder="Count" 
                      class="form-control"
                      autofocus/>
...

And in your view you can access all values like this:

...
for object_id in request.POST.getlist('item_id'): #this will contain a list with all item ids in it
    count = request.POST.get('count_%s'%object_id) #as html inputs are named with ids as part of name you can access them
    tag = request.POST.get('tag_%s'%object_id) #as html inputs are named with ids as part of name you can access them
    wishlist = WishListItem(owner=owner,
                    content_type=class_types[tag],
                    object_id=object_id,
                    tag=tag,
                    count=count)
    wishlist.save()
...



回答2:


I found the answer based on @datosula's answer.

since the product id may be repetitive because products are loaded from various tables, then a unique tag is required to distinguish returned values in views.py. I mixed up product's title and products type to achieve this:

<div class="form-group">

    <input type="hidden" name="title_type" value="{{ item.title }}{{ item.type }}">
    <input type="hidden" name="item_id_{{ item.title }}{{ item.type }}" value="{{ item.id }}">
    <input type="hidden" name="tag_{{ item.title }}{{ item.type }}" value="{{ item.type }}">
    <input type="hidden" name="title_{{ item.title }}{{ item.type }}" value="{{ item.title }}">
                                  
    <div class="text-center">
        <input  type="number" 
                id="count" 
                name="count_{{ item.title }}{{ item.type }}" 
                placeholder="count" 
                class="form-control"
                value="0"
                min="0"
                max="9999"
                autofocus/>
    </div>

</div>

in views.py I got the values and created the object like the following:

....
for item in request.POST.getlist('title_type'):
            object_id = request.POST.get('item_id_%s'%item)
            tag = request.POST.get('tag_%s'%item)
            print('\ntag: ', tag )
            print('\nclass_types[tag]: ', class_types[tag])
            count = request.POST.get('count_%s'%item)
            title = request.POST.get('title_%s'%item)
            if count != '0':  # only save those products that their count is not 0
                wishlist = WishListItem(owner=owner,
                                content_type=class_types[tag],
                                object_id=object_id,
                                tag=tag,
                                count=count,
                                title=title)
                wishlist.save()
....

wish it helps somebody



来源:https://stackoverflow.com/questions/65422388/how-to-name-numerous-dynamic-input-fields-for-post-method-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!