首页 > 解决方案 > 如何使用 POST 请求 Django 更改布尔值

问题描述

编辑:

我的目标是创建一个小型电子商务。在我的索引中,我有一个产品列表,其中一个属性是一个名为 in_cart 的布尔值,它说明产品是否在购物车中。默认情况下,所有布尔值都是假的。在我的模板中有一个包含所有产品的表格,我在其旁边放置了一个按钮“添加到购物车”,该按钮重定向到购物车模板。但是,当我单击添加到购物车时,所讨论的布尔值不会更改为 true。有什么想法吗?

    <table>
    <tr>
        <th>List of car parts available:</th>
    </tr>
    <tr>
        <th>Name</th>
        <th>Price</th>
    </tr>
    {% for product in products_list %}
    <tr>
      <td>{{ product.id }}</td>
      <td>{{ product.name }}</td>
      <td>${{ product.price }}</td>
      <td>{% if not product.in_cart %}
              <form action="{% url 'add_to_cart' product_id=product.id %}" method="POST">
                {% csrf_token %}
                <input type="submit" id="{{ button_id }}" value="Add to cart">
              </form>
          {% else %}
              {{ print }}
          {% endif %}
      </td>
    </tr>
    {% endfor %}
  </table>

  <a href="{% url 'cart' %}">See cart</a>

这些是我的观点:

def index(request):
    if request.method == "GET":
        products_list = Product.objects.all()
        template = loader.get_template('products/index.html')
        context = {'products_list': products_list}
        return HttpResponse(template.render(context, request))
    return HttpResponse('Method not allowed', status=405)


def cart(request):
    cart_list = Product.objects.filter(in_cart = True)
    template_cart = loader.get_template('cart/cart.html')
    context = {'cart_list': cart_list}
    return HttpResponse(template_cart.render(context, request))


def add_to_cart(request, product_id):
    if request.method == 'POST':
        try:
            product = Product.objects.get(pk=product_id)
            product.in_cart = True
            product.save()
        except Product.DoesNotExist:
            return HttpResponse('Product not found', status=404)
        except Exception:
            return HttpResponse('Internal Error', status=500)
    return HttpResponse('Method not allowed', status=405)

模型:

class Product(models.Model):
    name = models.CharField(max_length=200)
    price = models.IntegerField()
    in_cart = models.BooleanField(default=False)
    ordered = models.BooleanField(default=False)
    def __str__(self):
        return self.name

网址

urlpatterns = [
    path('', views.index, name='index'),
    path('cart/', views.cart, name='cart')
    re_path(r'^add_to_cart/(?P<product_id>[0-9]+)$', views.add_to_cart, name='add_to_cart')
]

我的终端出错

File "/Users/Nicolas/code/nicobarakat/labelachallenge/products/urls.py", line 8
    re_path(r'^add_to_cart/(?P<product_id>[0-9]+)$', views.add_to_cart, name='add_to_cart')
          ^
SyntaxError: invalid syntax

这是它在 localhost 中的样子: 指数

标签: pythondjangohtml-tableboolean

解决方案


首先,您的if声明无法访问。因为你之前有return过。当你调用return一个函数时,后面的函数return将不会执行。

所以你应该改变index功能。此外,您应该在您的发布请求中发送产品的标识符。标识符可以是模型中的 id 或任何其他唯一字段。

所以你的代码应该是这样的:

def index(request):
    if request.method == 'POST': # Request is post and you want to update a product.
        try:
            product = Product.objects.get(unique_field=request.POST.get("identifier")) # You should chnage `unique_field` with your unique filed name in the model and change `identifier` with the product identifier name in your form.
            product.in_cart = True
            product.save()
            return HttpResponse('', status=200)
        except Product.DoesNotExist: # There is no product with that identifier in your database. So a 404 response should return.
            return HttpResponse('Product not found', status=404)
        except Exception: # Other exceptions happened while you trying saving your model. you can add mor specific exception handeling codes here.
            return HttpResponse('Internal Error', status=500)
    elif request.method == "GET": # Request is get and you want to render template.
        products_list = Product.objects.all()
        template = loader.get_template('products/index.html')
        context = {'products_list': products_list}
        return HttpResponse(template.render(context, request))
    return HttpResponse('Method not allowed', status=405) # Request is not POST or GET, So we should not allow it.

我在代码的注释中添加了您需要的所有信息。我认为你应该花更多的时间在 python 和 django 文档上。但是,如果您还有任何疑问,可以在评论中提问。 问题编辑后 如果您不想在表单中使用只读字段,则应在代码中进行两项更改。首先,您应该在文件中添加一个带product_id参数的 url。urls.py像这样的东西:

url(r'^add_to_cart/(?P<product_id>[0-9]+)$', 'add_to_cart_view', name='add_to_cart')

然后,您应该从视图中添加单独的 add_to_cartindex视图。你的观点应该是这样的:

def index(request): 
    if request.method == "GET":
        products_list = Product.objects.all()
        template = loader.get_template('products/index.html')
        context = {'products_list': products_list}
        return HttpResponse(template.render(context, request))
    return HttpResponse('Method not allowed', status=405)


def cart(request):
    cart_list = Product.objects.filter(in_cart = True)
    template_cart = loader.get_template('cart/cart.html')
    context = {'cart_list': cart_list}
    return HttpResponse(template_cart.render(context, request))


def add_to_cart(request, product_id):
    if request.method == 'POST':
        try:
            product = Product.objects.get(pk=product_id)
            product.in_cart = True
            product.save()
            return HttpResponse('', status=200)
        except Product.DoesNotExist:
            return HttpResponse('Product not found', status=404)
        except Exception:
            return HttpResponse('Internal Error', status=500)
    return HttpResponse('Method not allowed', status=405)

现在您应该将表单的操作链接更改为:

{% url 'add_to_cart' product_id=product.id %}

推荐阅读