Yahya
Yahya

Reputation: 53

How to update my Django database with a submit button?

I am creating a web application that will serve as a grocery store. The way I set it up is so the customer can come onto the website, click on the items that they would like to purchase, and then click a submit button to purchase those items. The problem I am running into is having a views.py function to take the information of which products were selected and subtracting 1 from the quantity of the database.

"""models.py"""
class Post(models.Model):
    title = models.CharField(max_length=100)
    Price = models.DecimalField(max_digits=4, decimal_places=2,default=1)
    Sale = models.DecimalField(max_digits=4, decimal_places=2,default=1)
    quantity = models.IntegerField(default=1)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    category = TreeForeignKey('Category',null=True,blank=True, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('post-detail', kwargs={'pk': self.pk})

views.py

class PostListView(ListView):
    model = Post
    template_name = 'blog/home.html'  # <app>/<model>_<viewtype>.html
    context_object_name = 'posts'

def inventory(request):
    products = request.POST.getlist('products')
    for product in products:
        a = Post.objects.get(title=product)
        a.quantity = a.quantity -1
        a.save()
    print(products) # This line isn't necessary but it will show what is in your list from the terminal.
    return redirect('blog-home')

urls.py

    path('user/<str:username>', UserPostListView.as_view(), name='user-posts'),
    path('inventory', views.inventory, name='inventory'),

home.html

{% extends "blog/base.html" %}
{% block content %}
    <form action="{% url 'inventory' %}" method="POST" id="menuForm">
      {% for post in posts %}
        {% if post.quantity > 0 %}
            <article class="media content-section">
              <div class="media-body">
                <div class="article-metadata">
                  <a class="mr-2">{{ post.category }}</a>
                </div>
                <h2><a class="article-title" >{{ post.title }}</a></h2>
                <p class="article-content"> Price: ${{ post.Price }}</p>
                <p class="article-content"> Sale: ${{ post.Sale }}</p>
                <input type="checkbox" id="product_{{ post.id }}" value="{{ post.title }}" form="menuForm" name="products" > Inventory count: {{ post.quantity }}
              </input>
              </div>
            </article>
        {% else %}
        {% endif %}
      {% endfor %}
      <button type="submit" form="menuForm">Confirm Purchase</button>
    </form>
{% endblock content %}

My goal is to click on the checkboxes, and when the customer clicks the button on the bottom of home.html, it triggers the inventory function to subtract "1" from the quantity. When I say print(products), then the terminal gives me the title of all the posts that are check-marked. However, it still isn't going into the database and subtracting 1 from the inventory. (I solved it)

Upvotes: 1

Views: 612

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476557

Using Post.objects.get('products[x]') does not make sence, the .get(…) method [Django-doc] expects Q objects as positional parameters, or named parameters, so for example:

from django.shortcuts import redirect

def inventory(request):
    products = request.POST.getlist('products')
    Post.objects.filter(pk__in=products).update(
        quantity=F('quantity')-1
    )
    return redirect('profile')

By using a .update(…) [Django-doc] you decrement all Posts in bulk which is more efficient than making two database queries per Post object.

Using HttpResponseRedirect("{% url 'profile'%}") will not work either. The "{% url 'profile'%}" is just a string, it does not perform any template rendering. Django will normally return a HTTP 302 response, with {% url 'profile' %} as link to go to, but the browser does not understand {% url 'profile' %}, it can only work with a URI.

Upvotes: 1

Related Questions