[Django]-How to change data in database by clicking a button in HTML with Django

3👍

You can do that way

from django.db.models import F
def questions(request)
     _reponse = Reponse.objects.update(total=F('total') + 1)

      return render(request, 'vautmieux/test.html', {'reponse': _reponse})

If you want to add a button to increase the counter so you need to create two separate views one to render the html page and the other to increase the integerfield
So you views.py will look like this

from django.db.models import F
from django.views.decorators.csrf import csrf_exempt
def questions(request)      
      return render(request, 'vautmieux/test.html', {'reponse': _reponse})
@csrf_exempt
def IncreaseCounter(request):
    _reponse = Reponse.objects.update(total=F('total') + 1)
    return HttpResponse('the counter has been increased')

and in your url you will have :

path('question_page/', views.questions, name='question-html'),
path('increase_counter/', views.IncreaseCounter, name='Increase-Counter')

And last you need just to add a button to target the second view :

<button onclick="window.location.href='/increase_counter/';"> + 1 </button>

And the ideal way is to use ajax so your page will not refresh every time you click the button, to do so you have to change the onclick function of the button and to add the following script :

<button onclick="increase_counter()"> + 1 </button>

<script type="text/javascript">
             $.ajax({
             url: '/increase_counter/',
             method : 'POST',
             success: function(response) {

              alert('counter increased')
              }
              }); 
</script>

But if you want to use ajax you have to add a csrf_exempt decorator on your view.

In order to update a specific object in your model you need to pass the pk as a variable in your url like so :

path('increase_counter/<int:pk>/', views.IncreaseCounter, name='Increase-Counter')

in your button you will loop change the button to be like this :

<button onclick="window.location.href='/increase_counter/{{ response.pk }}/';"> + 1 </button>

for aajax is the same method you add the pk into the url.
And in your view you will add this :

def IncreaseCounter(request, pk):
    _reponse = Reponse.objects.filter(pk=pk).update(total=F('total') + 1)
    return HttpResponse('the counter has been increased')

0👍

In my opinion, this is a much easier straightforward method. This isn’t exact code for your problem, but more of a general flow on what the heck all this stuff is and how to use it. So apologies on the wordiness of this post. I am posting for my case because I think will be useful to you as you expand your app to needing to control totals for a particular object. So, in my case, I was needing a button to easily increase or decrease a part quantity for an inventory system, like nuts and bolts. This is what I needed to control inventory while on a part-specific page:

  1. A button with a reverse pattern name that links to increase_inventory view.

    <a href="{% url 'webapp:increase-inventory' part.pk %}" ><button class="btn btn-primary">Add 1</button></a>

Notice the "parts.pk", I’m going to talk about it in sec. Also, now and later notice the differences between _ and -. When you see -, it’s a pattern name.

  1. In your urls.py, place a similar code like this in your file.

     urlpatterns = [
     path('increase_inventory_level/<pk>', views.increase_inventory, name='increase-inventory'), ]
    

Notice a few things here too,
"inventory-level" is the pattern name which is the linking variable between your html page and urls.py.
"increase_inventory_level/<pk" is the URL link for a specific object. Say in your parts list you have: a nut, a bolt, and an o-ring. Each one of these objects is going to have a different PK. Each one of these items has it’s own detail page which is going to have its own url, which will look something like this partdetail/<pk. (Close those brackets for pk, I can’t in this post or it will disappear)

The last thing to notice is the "views.increase_inventory". This links your app to the specific view that you need.

def increase_inventory(request, *args, **kwargs):
    pk = kwargs.get('pk')
    part = get_object_or_404(Part, pk=pk)
    part.inventory_level = part.inventory_level + 1
    part.save()

    context = {'part': part}

    return render(
        request,
        'webapp/part_detail.html',
        context=context
    )

Now we’re cooking. The view grabs the object associated with the PK value then edits the inventory attribute of the part object, saves it, and then renders the html page with the new part information.

Leave a comment