简体   繁体   中英

Django, Ajax and jQuery - posting form without reloading page and printing “succes” message for user

I would like to kindly ask you for your help. I wanted to create simple voting system. I somehow succeeded. I have simple "UP" button that post form with simple +1 integer for scorevalue of post. It have a lot of problems right now but I will fight with them later.

Right now I wanted to add this +1 score without refreshing page (like most modern websites). I did my googling and I came up with this: https://www.codingforentrepreneurs.com/blog/ajaxify-django-forms/ I have to say that it is working quite well, even with my zero knowledge about js, jquery or ajax.

My problem is, that javascript is adding this +1 but it also is giving me some errors that I cannot grasp:

responseText: "TypeError at /viewquestion/6/voteup\n__init__() missing 1 required positional argument: 'data'\n\nRequest Method: POST\nRequest URL: http://127.0.0.1:8000/viewquestion/6/voteup\nDjango Version: 3.0.4\n

I would like to either get rid of them or understand nature of them:P

And my second or main problem is that. Voting is working, but score don't change because ofcourse, page is not reloading. And I also cannot print "Success voting" message for user because, well website is not refreshing.

Giving user some simple message "Voting Success" would be enough for me. Best case scenario would be updating score immediately, but I don't know how much it would complicate things.

Can you please help me with this or point me in right direction? It is quite hard for me to come up even with googling ideas since I have no knowledge in js/ajax or jquery.

Here is what I was able to do right now:

base.html:

<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
<script>
// using jQuery
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]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

var csrftoken = getCookie('csrftoken');

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});
</script>

views.py:

@login_required()
def questionvoteup(request, question_pk):
    question = get_object_or_404(Question, pk=question_pk, user=request.user)
    if request.is_ajax() and request.method == "POST":
        question.votesscore += 1
        question.amountofvotes += 1
        question.save()
        messages.success(request, 'Thank you for your vote!')
        return JsonResponse()
    else:
        return HttpResponse(400, 'Invalid form')

home.html:

<ul>
    {% for question in allquestionswithanswers %}
    <li>
        {{ question }} Score: {{ question.votesscore }} {{ question.user }}

        {% if messages %}

        {% for message in messages %}
        {{ message }}
        {% endfor %}

        {% endif %}

        <br><br>

        <form class='my-ajax-form' method='POST' action='.' data-url="{% url 'questionvoteup' question.id %}" >
        {% csrf_token %}
        <button type='submit'>UP</button>
        </form>



        {% for answer in question.answer_set.all %}
            {{ answer }}<br>
        {% endfor %}
    </li>
    {% endfor %}

</ul>

Thank you.

JsonResponse : the first parameter, data, should be a dict instance.

Your view:

def questionvoteup(request, question_pk):
    question = get_object_or_404(Question, pk=question_pk, user=request.user)
    if request.is_ajax() and request.method == "POST":
        question.votesscore += 1
        question.amountofvotes += 1
        question.save()
        data = {
            "msg": 'Thank you for your vote!'
        }
        return JsonResponse(data)
    else:
        return HttpResponse(400, 'Invalid form')

Than in your template:

$(".my-ajax-form").submit(function(e) {
    e.preventDefault(); // avoid to execute the actual submit of the form.
    var form = $(this);
    var url = form.data('url');

    $.post(url).done(function(data) {
        alert(data.msg); // get your response data

    });

});

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