0

in the last days i trying to learn form submission using AJAX and django in backend.

I can take successfully form inputs values using AJAX in django views.py (validate_number) (working) follow this example . in this views.py validate_number i calculate NEW sum of numbers and i want this sum value to render back to html page,but i don't know how to do.

any idea how to render results from AJAX request back to html page ?

here the code

html form :

<form id="form" action='' data-validate-number-url="{% url 'validate_number' %}" method="POST" enctype="multipart/form-data">{% csrf_token %}
<div class="form-group col-md-6">
Select the C Raster Dataset:<br>
   <select name="CC" class="form-control" id="CC"> 
    <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
  </select>
Select the P:<br>
   <select name="PP" class="form-control" id="PP">
     <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
  </select>
Select the F:<br>
   <select name="FF" class="form-control" id="FF">
    <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
  </select>
    </div>
<button type="button" class="btn btn-primary next-step1">Save and continue</button>


    <p>{{sum}}</p>


Select the GG:<br>
   <select name="G" class="form-control" id="GG">
    <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
  </select>
Select the JJ:<br>
   <select name="JJ" class="form-control" id="JJ">
    <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
  </select>
<button type="button" class="btn btn-primary next-step">Save and continue</button>
Select the FINAL:<br>
   <select name="FINAL" class="form-control" id="FINAL">
    <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
    <option value="10">ten</option>
  </select>
 <button type="submit" class="btn btn-primary">Save</button>
</form>

AJAX

$(".next-step1").click(function (e) {
var form = $(this).closest("form");
var number1 = $("#CC").val();
var number2 = $("#PP").val();
$.ajax({
url: form.attr("data-validate-number-url"),
data:  {
      'number1': number1,
      'number2':number2
    },
dataType: 'json',
success: function (data) {
}
});

urls.py:

url(r'^details/(?P<slug>[^\.]+)/$', views.blog_details, name='blog_details'),
url(r'^ajax/validate_number/$', views.validate_number, name='validate_number'),

views.py

def blog_details(request,slug):
    posts=mymodel.objects.all()
    post=get_object_or_404(posts, slug_title=slug)
    return render(request,'index.html',{'post':post})


def validate_number(request):
    number1 = request.GET.get('number1', None)
    print number1
    number2 = request.GET.get('number2', None)
    print number2
    sum=int(number1)+int(number2)
    return JsonResponse(sum)

2 Answers 2

1

I am going to present here a minimal application of computation. We give two numbers with the operation wish, django does the calculation and returns the answer in json. Note that, I used the ajax / jquery callback concept and disable the csrf control in the django view with csrf_exempt.

HTML/javaScript:

    <div class="container">
        <form class="col-lg-6" id="form">
          <legend>Select number to make an operation</legend>
            Number 1: <input type="number" class="form-control" id="n1">
            Number 2: <input type="number" class="form-control" id="n2">
            Select operation:
              <select class="form-control" name="op" id="op">
                <option value="+">+</option>
                <option value="-">-</option>
                <option value="*">*</option>
              </select>
            <input type="submit" id="submit" value="Send">
        </form>
        <div>
            <h2 class="result-box">The result is : <strong id="result"></strong></h2>
        </div>
    </div>


    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>

    <script type="text/javascript">
        $(function() {
            function call_ajax(f) {
                const n1 = $('#n1').val();
                const n2 = $('#n2').val();
                const op = $('#form option:selected').text();
                const data = {n1: n1, n2: n2, op: op}
                // you can verify the data in the browser console
                console.log(data);
                $.ajax({
                    url: '/ajax/make_operation/',
                    data: data,
                    type: 'POST',
                    success: f,
                    error: function(error) {
                        console.log(error);
                    }
                });
            }

            function server_response(response) {
                // convert to json format
                const r = JSON.parse(response);
                console.log(r);
                // include the result in the dom
                var text = document.createElement('i');
                text.innerHTML = '<strong id="result">' + r.result + '</strong>';
                $('#result').replaceWith(text);
            }

            //Validate
            $('#form').submit(function(e) {
                e.preventDefault();
                call_ajax(server_response);
            });
        });
    </script>
  </body>
</html>

views.py:

    from django.shortcuts import render
    from django.http import JsonResponse
    from django.views.decorators.csrf import csrf_exempt
    import json


    @csrf_exempt
    def make_operation(request):
    if request.method == 'POST':
        # recovert the data sending by the ajax post request
        number1 = int(request.POST['n1'])
        number2 = int(request.POST['n2'])
        operation = request.POST['op']
        print(operation)
        result = None

        # make the operation
        if operation is '+':
            result = number1 + number2
        elif operation is '-':
            result = number1 - number2
        elif operation is '*':
            result = number1 * number2
        else:
            result = number1 + number2

        # return the result to the ajax callback function
        return JsonResponse(json.dumps({'result': result}), safe=False)
    return render(request, 'index.html')

urls.py

from django.contrib import admin
from django.urls import path
from ajax import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('ajax/make_operation/', views.make_operation),
]

So the are many options to do this. I have show only one way to do ajax with django(without django-form).

Sign up to request clarification or add additional context in comments.

1 Comment

you show me a great example thank you ,but in my case i have two different views.py , how to do this ?
1

In your AJAX success block, you have to tell it what you want it to do with the information:

$(".next-step1").click(function (e) {
var form = $(this).closest("form");
var number1 = $("#CC").val();
var number2 = $("#PP").val();
$.ajax({
url: form.attr("data-validate-number-url"),
data:  {
      'number1': number1,
      'number2':number2
    },
dataType: 'json',
success: function (data) {
// 'data' is the dictionary received from the view.
// You could call it whatever you want.
    $('#sum).html(data.sum_json);
    /* Find 'id="sum"' and replace what's inside the tags(or innerHTML)
       with the dictionary value of 'sum_json'.
       If other keys exist in the 'data' dictionary,
       they are accessed the same way, as in 'data.sum_json_2'.
    */
}
});

index.html

<form id="form" action='' data-validate-number-url="{% url 'validate_number' %}" method="POST" enctype="multipart/form-data">{% csrf_token %}
<div class="form-group col-md-6">
Select the C Raster Dataset:<br>
   <select name="CC" class="form-control" id="CC"> 
    <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
  </select>
Select the P:<br>
   <select name="PP" class="form-control" id="PP">
     <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
  </select>
Select the F:<br>
   <select name="FF" class="form-control" id="FF">
    <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
  </select>
    </div>
<button type="button" class="btn btn-primary next-step1">Save and continue</button>


    <p id="sum"></p>


Select the GG:<br>
   <select name="G" class="form-control" id="GG">
    <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
  </select>
Select the JJ:<br>
   <select name="JJ" class="form-control" id="JJ">
    <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
  </select>
<button type="button" class="btn btn-primary next-step">Save and continue</button>
Select the FINAL:<br>
   <select name="FINAL" class="form-control" id="FINAL">
    <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
    <option value="10">ten</option>
  </select>
 <button type="submit" class="btn btn-primary">Save</button>
</form>

view

def blog_details(request,slug):
    posts=mymodel.objects.all()
    post=get_object_or_404(posts, slug_title=slug)
    return render(request,'index.html',{'post':post})


def validate_number(request):
    # You had request.GET, but your form method is POST.
    number1 = request.POST.get('number1', None)
    print number1
    number2 = request.POST.get('number2', None)
    print number2
    sum=int(number1)+int(number2)
    # render a template with the given key: value to be sent to AJAX.
    sum_json = render_to_string('sum_template.html', {'sum': sum})
    """
    Assuming the information for sum_2 etc. uses the same format,
    we can use the same template
    """
    sum_json_2 = render_to_string('sum_template.html', {'sum': sum_2})
    # Send the dictionary to AJAX. This is what we called 'data'.
    return JsonResponse({'sum_json': sum_json, 'sum_json_2': sum_json_2})

This is the template that we render_to_string to send to the AJAX. It renders templates the same way render does.

sum_template.html

{{ sum }}

You do not want to render_to_string index.html because you insert the whole index template inside the <p>, not just sum. You probably also want to add an if statement to your view

if request.is_ajax() and request.POST:

to filter out the non-AJAX requests.

I've been told there are better ways to do it. I just figured all this out myself, and don't know what they are. If you need more detail let me know.

4 Comments

how to send sum from views.py to AJAX success block ?
Sorry. Updated answer
I saw you haven't marked an answer yet. I updated mine again. I know this works
can you explain me how this work for multiple values ?for example if i have sum1,sum2,sum3 ?i try to use something likes this : sum_json_1= render_to_string('index.html', {'sum1': sum1}) sum_json_2 = render_to_string('index.html', {'sum2':sum2}) return JsonResponse({'sum_json_1': sum_json_1,'sum_json_2': sum_json_2}) and in ajax : $('#sum1).html(data.sum_json_1); $('#sum2).html(data.sum_json_2); but not work

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.