Using Ajax to change a Boolean in a Django Model using a Button

Viewed 55

I am trying to send a post in a Django project to switch a boolean from False to True. The button is working fine but I want to click it without refreshing the page so I am trying to use Ajax but I keep getting {"status": "error"} for a bad request and not sure why.

Here is the views:

def change_status(request, id):
    if request.is_ajax() and request.method == 'POST':
        startsession = Workout.objects.get(id=id)
        startsession.active = True if request.POST.get('active') == 'true' else False
        startsession.save()
        data = {'status': 'success', 'active': startsession.active}
        return JsonResponse(data, status=200)
    else:
        data = {'status': 'error'}
        return JsonResponse(data, status=400)

Here is the template:

        <div>
          {% if object.active %}
            <button disabled  type="button">Start the workout</button>
          {% else %}
              <a href="{% url 'my_gym:bla' object.id %}">
              <button id="customSwitches" onclick="start();" type="button">Start the workout</button>
              </a>
          {% endif %}
        </div>

Here is the ajax script

        <script>
                    $(document).ready(function()
                    $("#customSwitches").on('click', function () {
                      $.ajax({
                        url: "{% url 'my_gym:bla' object.id %}",
                        data: {
                          csrfmiddlewaretoken: "{{ csrf_token }}",
                          active: this.disabled
                        },
                        type: "POST",
                        dataType: 'json',

                      });
                      .done(function(data) {
                          console.log(data);
                      })
                      .always(function() {
                          console.log('[Done]');
                      })
                    })
                    });
        </script>

it is working fine with the following views.py:

def change_status(request, id):
    url = request.META.get('HTTP_REFERER')  # get last url
    startsession = Workout.objects.get(id=id)
    startsession.active = True
    startsession.save()
    return HttpResponseRedirect(url)

--------------------------------------Update------------------------------------------------------

Here is another trial which is returning nothing at all no response:

def change_status(request,id):
    # startsession = get_object_or_404(ActiveSession, id=id)
    startsession = Workout.objects.get(id=id)
    startsession.active = True
    startsession.save()
    context = {
        'startsession': startsession,
    }
    if request.is_ajax:
        html = render_to_string('my_gym/start_workout.html', context, request=request)
        return JsonResponse({'form': html})

here is the template and script:

{{ object.active }}
    <div id="startworkout">
      <form action="{% url 'my_gym:bla' object.id %}" method='post'>
          {% csrf_token %}
              {% if object.active %}
              <button disabled  type="button" class="mt-3 btn btn-dark btn-block mb-4 ripple-surface">Start the workout</button>
              {% else %}
                <button id="customSwitches" onclick="start();" type="button" class="mt-3 btn btn-dark btn-block mb-4 ripple-surface">Start the workout</button>
              {% endif  %}
      </form>
    </div>

    <script type="text/javascript">
        $(document).ready(function(event){     <-------- error here
            $(document).on('click','#customSwitches', function(event){
                event.preventDefault();
                var id= $(this).attr('value');
                $.ajax({
                    type:'POST',
                    url:'{% url 'my_gym:bla' object.id %}',
                    data:{'id': id, 'csrfmiddlewaretoken':'{{csrf_token}}'},
                    dataType:'json',
                    success:function(response){
                        $('#startworkout').html(response['form'])
                        console.log($('#startworkout').html(response['form']));
                    },
                    error:function(rs, e){
                        console.log(rs.responseText);
                    },
                });
            });
        });
    </script>

here is the error in the console: Uncaught ReferenceError: $ is not defined at (index):145:9 which is related to $(document).ready(function(event){ Question: How can I add ajax to the following views to prevent the page from refreshing everytime the button is clicked

Thank you

1 Answers

You code on template is the problem {% if object.active %} this django code will only work on the initialization of the page. you can try my code below:

TEMPLATE:

<script> const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value; </script>

    <div id='divAppend'></div>

    $.ajax({
    url: "{% url 'YOUR URL' %}",
    type: "POST",
    data: {
      'active' : 'True or False' 
    },
    headers: { 'X-CSRFToken': csrftoken },
    success: function (data) {
      $('#divAppend').html()
      html_val=""
      
      if(data.status !== ''){
        html_val+='<button disabled  type="button">Start the workout</button>'
      }
      else{
        html_val+='<a href="{% url 'my_gym:bla' object.id %}">'
        html_val+='<button id="customSwitches" onclick="start();" type="button">Start the workout</button>'
        html_val+='</a>'
      }

      $('#divAppend').append(html_val)

    },
    error: function(){
        console.log('Error. Failed to update the details!...');
    }
  })

YOU VIEWS.PY

def change_status(request, id):
    context = {}

    if request.is_ajax() and request.method == 'POST':
        startsession = Workout.objects.get(id=id)
        startsession.active = True if request.POST.get('active') == 'true' else False
        startsession.save()
        context.update({'status': 'success'})
        context.update({'active': str(startsession.active)})
    else:
        context.update({'status': 'error'})
        context.update({'active': ''})

    return JsonResponse(data=context)
Related