Как передать <select>в View с использованием Django - PullRequest
0 голосов
/ 12 октября 2019

Я пытался создать систему тележек в Django и хотел передать Размер и Количество товара как <Select>

, введенный в View. Мой шаблон имеет:

<ul class="list-unstyled">
              Select Size:
              <select  name="sizes">
                {% for size in product.sizes.all %}
                <li class="list-item list-inline-item"><option value="{{size.nameSize}}">{{size.nameSize}}</option> </li>
                {% endfor %}
              </select>


          </ul>

Вот как это выглядит:

WebpageProduct

Но когда я отправляю его, используя Добавить в корзинуКнопка Я получаю ошибку:

Error Part 1 Error Part 2

Это код в представлении:

def add_item(request,pk):
product = get_object_or_404(Product,pk=pk)
size = request.POST['sizes']
selectsize = Size.objects.get(nameSize=size)
user = request.user
usercart = Cart.objects.get(owner=user)
newitem = CartItems.objects.create(cart = usercart,product=product,size=selectsize) 
items = usercart.cartitems
return render(request,'cart.html',{'cartitems':items})

Я пытаюсь использовать имя размера из шаблона и сравнить имя размера, которое у меня есть в базе данных для этого продукта. Используя:

selectsize = Size.objects.get(nameSize=size)

Мне удалось получить размер с именем 36, поэтому яхотел передать значение 36 из шаблона в переменный размер, используя post.

Но я получил упомянутое сообщение об ошибке, которое, как я считаю, связано с тем, что имя для <select> является общим для всех <option>.

Если я могу либо получить альтернативный способ сделать это, либо решить эту ошибку, оба типа решений приветствуются. * Я не использую формы Django, потому что я не знаю, как отображать формы Django, как я показываю свои продукты в корзине и на странице продукта.

ОТВЕТ

Мне не хватало кнопки отправки, и я скорее использовал <a href="{% url 'add_item' product.pk %}>Add To Cart</a>" для отправки формы, которая не работала. Теперь я заменил его на <button class="btn btn-success" style="margin-top: 10px;" type="submit">Add To Cart New</button> И в форме «Действие» дается ссылка, на которую я пытался перейти.

 <form method="post" enctype="multipart/form-data" action="{% url 'add_item' product.pk %}">

Глупая ошибка на моей стороне.

Спасибо за ответы.

Ответы [ 2 ]

2 голосов
/ 12 октября 2019

Расширение того, что сказал @Yevhenii M., и, в частности, речь идет о MultiValueDictKeyError:

Эта ошибка возникает, когда данный ключ (sizes в этом случае) не найден в диктовке POST. Это может происходить (я только догадываюсь, поскольку вы не опубликовали полный HTML-код), потому что вы не поместили соответствующий тег <form> вокруг select. Итак, окончательный код будет выглядеть примерно так:

<form action="url-to-send-form-data" method="POST">
    {% csrf_token %}
    <select name="sizes">
    {% for size in product.sizes.all %}
        <option value="{{size.nameSize}}">{{size.nameSize}}</option>
    {% endfor %}
    </select>
</form>

{% csrf_token %} необходим для защиты от атак подделки межсайтовых запросов (подробнее: https://docs.djangoproject.com/en/2.2/ref/csrf/)


РЕДАКТИРОВАТЬ: Теперь, когда я посмотрю поближе, сообщение об ошибке показывает, что URL вызывается с помощью запроса GET (возможно, из-за попытки доступа к / item_added / 1 прямо из URL браузера). Именно поэтому django не может найти ключ sizes.

Один из распространенных способов вызова URL по почте, как показано в фрагменте кода выше, и добавление подтвержденияКнопка на HTML:

    ...
    <button type="submit">Submit</button>
</form>
2 голосов
/ 12 октября 2019
  1. Вам не нужно использовать тег <ul> здесь.

Вы можете написать:

Select Size:
<select  name="sizes">
    {% for size in product.sizes.all %}
        <option value="{{size.nameSize}}">{{size.nameSize}}</option>
    {% endfor %}
</select>

и результат будет таким же.

Поскольку вы не указали, что add_item(request, pk) работает только по протоколу POST, вы не можете ожидать, что запрос будет представлен всегда.

Лучше напишите свой код следующим образом:

if request.POST:
    # do something

И если вы не укажете значение по умолчанию для вашего выбора в шаблоне, то sizes не будет в вашем request.POST. Вы можете написать так, просто чтобы быть уверенным, что вы получили какое-то значение:

request.POST.get('sizes', 'some_default_value')
Только потому, что вы получаете MultiValueDictKeyError, вам нужно посмотреть, что вы получите в запросе. Возможно, вы получите QueryDict, тогда вам нужно извлечь первое значение. Например, посмотрите этот SO вопрос . Например, напечатайте ваш запрос. Проверьте или проверьте тип.
...