【问题标题】:How to pass a <select> in a View using Django如何使用 Django 在视图中传递 <select>
【发布时间】:2020-02-09 18:11:29
【问题描述】:

我试图在 Django 中创建一个购物车系统,并希望将产品的尺寸和数量传递为 &lt;Select&gt;

在视图中输入。 我的模板有:

<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>

这就是它的样子:

但是当我使用添加到购物车按钮提交它时,我得到了错误:

这是视图中的代码:

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 的大小,因此我想使用 post 将值 36 从模板传递给可变大小。

但我得到了提到的错误,我认为这是因为&lt;select&gt; 的名称在所有&lt;option&gt; 中都很常见。

如果我能找到另一种方法来做到这一点或解决这个错误,那么两种类型的解决方案都受到欢迎。 *我没有使用 Django Forms,因为我不知道如何显示 django 表单,就像我在购物车和产品页面上显示我的产品一样。

回答

我错过了提交按钮,而是使用&lt;a href="{% url 'add_item' product.pk %}&gt;Add To Cart&lt;/a&gt;" 提交不起作用的表单。 现在我将其替换为&lt;button class="btn btn-success" style="margin-top: 10px;" type="submit"&gt;Add To Cart New&lt;/button&gt; 并且表单 Action 给出了我试图去的链接。

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

我犯了一个愚蠢的错误。

感谢您的回答。

【问题讨论】:

    标签: django python-3.x django-forms django-views


    【解决方案1】:

    扩展@Yevhenii M. 所说的内容,并特别谈论MultiValueDictKeyError

    当在 POST 字典中找不到给定键(在本例中为 sizes)时,会发生此错误。这可能正在发生(我只是在猜测,因为您没有发布完整的 html 代码),因为您没有在 select 周围放置相应的 &lt;form&gt; 标记。 所以,最终的代码看起来像这样:

    <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/


    编辑: 现在我仔细查看,错误消息显示正在使用 GET 请求调用 url(可能是因为试图访问 /item_added/1 直接来自浏览器的 url)。这就是 django 找不到 sizes 键的原因。

    通过post调用url的一种常见方式,如上面的代码片段所示,并在html中添加一个提交按钮:

        ...
        <button type="submit">Submit</button>
    </form>
    
    【解决方案2】:
    1. 这里不需要使用&lt;ul&gt;标签。

    你可以写:

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

    结果是一样的。

    1. 由于您没有指定 add_item(request, pk) 只能通过 POST 工作,因此您不能指望 request.POST 总是会出现。

    最好这样写你的代码:

    if request.POST:
        # do something
    

    如果您没有在模板中为您的选择指定默认值,那么sizes 将不会出现在您的request.POST 中。 你可以这样写,以确保你得到了一些价值:

    request.POST.get('sizes', 'some_default_value')
    
    1. 仅仅因为你得到了MultiValueDictKeyError,你需要看看你在请求中得到了什么。也许你得到 QueryDict,那么你需要提取第一个值。例如,请参阅此SO question。例如,打印您的 request.POST 或检查类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-23
      • 2015-12-23
      • 1970-01-01
      • 2015-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多