简体   繁体   中英

How do I get multiple post requests from Django and Ajax on the same page working?

I have been banging my head over this all day long. Nothing seems to be working. Here's my situation.

I have a Django form with two fields: redirect_from , redirect_to . There are two submit buttons to this form: Validate and Save . When the page loads, Submit is hidden and only Validate is shown.

So now, when the user fills the two fields and clicks Validate I used Ajax to confirm that both the fields are the same. If they are, show the Save button. Clicking the Save button should save the form to the database. I also put in an oninput listener so that after the Ajax call is made, if the user tries to change the data, the Save button is hidden again and he has to now evaluate it again.

Apparently this is supposed to be easy with Ajax, but I'm finding it extremely difficult and frustrating. This is my code so far:

My Template:

form method="post">
        {% csrf_token %}
        {% include 'partials/form_field.html' with field=form.redirect_from %}
        {% include 'partials/form_field.html' with field=form.redirect_to %}
        <button id="submit" class="btn btn-lg btn-primary" type="submit" name="save" value="Save">Save</button>
        <button id="ajax_submit" class="btn btn-lg btn-primary" type="submit" name="ajax" value="Ajax">Validate</button>
    </form>


{% endblock %}


{% block extra_scripts %}
{{ block.super }}

<script type="text/javascript">

    $(document).ready(function() {
        $("#submit").hide()
    });

    $('#id_redirect_to').on('input', function(){
        $("#submit").hide()
    });


    console.log("hello")
    //For getting CSRF token
            function getCookie(name) {
                var cookieValue = null;
                if (document.cookie && document.cookie != '') {
                    var cookies = document.cookie.split(';');
                for (var i = 0; i < cookies.length; i++) {
                    var cookie = jQuery.trim(cookies[i]);


                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                  cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                   }
                }
             }
        return cookieValue;
  }


    //For doing AJAX post

    //When submit is click
     $("#ajax_submit").click(function(e) {
         console.log("Clicked")


     e.preventDefault();

    //Prepare csrf token
     var csrftoken = getCookie('csrftoken');


    //Collect data from fields
     /*var email = $('#inputEmail').val();*/
     var redirect_from= $('#id_redirect_from').val();
     var redirect_to= $('#id_redirect_to').val();
     console.log("URL from and to is", redirect_from, redirect_to)
     /*var password = $('#inputPassword').val();*/


    //Send data
     $.ajax({
           url : window.location.href, // the endpoint,commonly same url
           type : "POST", // http method
           data : { csrfmiddlewaretoken : csrftoken,
           redirect_from : redirect_from,
           redirect_to : redirect_to
           /*password : password*/
     }, // data sent with the post request

     // handle a successful response
     success : function(json) {
     console.log(json); // another sanity check
     //On success show the data posted to server as a message
         if (json['redirect_success'] === 'true')
         {
             alert("They are the same!" +json['redirect_success'] +'!.' );
             $("#submit").show()
         }
         else
         {
             $("#submit").hide() //Maybe display some error message in the future!
         }
     },

     // handle a non-successful response
     error : function(xhr,errmsg,err) {
     console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
     }
     });
    });


</script>

{% endblock extra_scripts %}

My Views:

def edit_redirect(request, pk):
    if request.method == 'GET':
        red_url = MarketingRedirect.objects.get(pk=pk)
        data = {'redirect_from': red_url.redirect_from, 'redirect_to': red_url.redirect_to}
        form = RedirectEditForm(initial=data)
        return render (request, 'marketing_redirect/edit_redirect.html', {'form': form,
                                                                                       'redirect_from':  red_url.redirect_from})

    if request.POST['save'] == 'Save':
        form = RedirectEditForm(request.POST)
        if form.is_valid():
            red_url = MarketingRedirect.objects.get(pk=pk)
            data = form.cleaned_data
            red_url.redirect_from = data['redirect_from']
            red_url.redirect_to = data['redirect_to']
            red_url.save()
            return redirect('backend_redirect')

    if request.POST['ajax'] == 'Ajax':
        if request.is_ajax():
            redirect_from = request.POST.get('redirect_from')
            redirect_to = request.POST.get('redirect_to')
            if redirect_from == redirect_to:
                data = {'redirect_success': 'true'}
                return JsonResponse(data)
            else:
                data = {'redirect_success': 'false'}
                return JsonResponse(data)

I'm getting a 500: MultiValueDictKeyError at "'Save'"

Could someone guide me in the right direction here? Very new to ajax.

This is due to using the button click events and not a form submit to preform the Ajax call. Ajax is not sending the button name attributes. You will need to manually add the button 'name' parameter to the data sent via Ajax, like so:

data : { csrfmiddlewaretoken : csrftoken,
       redirect_from : redirect_from,
       redirect_to : redirect_to,
       action: 'ajax' 
}

The use this in your view to capture if the Ajax request has been received:

if request.POST.get('action') == 'ajax':
    # do ajax stuff here

Also as good practice I would be use 'safer' naming conventions to in order to avoid confusion. Like possibly changing the 'ajax' to 'verify' etc...

I forgot to mention you will need to remove the type="submit" from the Ajax button.

Hope this helps :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM