Ajax не работает в посте Django - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь использовать ajax в Django для публикации комментариев на новостном веб-сайте. Однако, это не работает. Когда я нажимаю кнопку отправки, она все равно обновляет страницу и не имеет значения, как никакой ajax.

Я действительно новичок в Django и Ajax. Любой друг может помочь мне решить эту проблему?

Вот мой view.py:

def newsDetailView(request, news_pk):
    news = News.objects.get(id=news_pk)
    title = news.title
    author = news.author_name
    add_time = news.add_time
    content = news.content
    category = news.category
    tags = news.tag.annotate(news_count=Count('news'))

    all_comments = NewsComments.objects.filter(news=news)

    comment_form = CommentForm(request.POST or None)
    if request.method == 'POST' and comment_form.is_valid():
        if not request.user.is_authenticated:
            return render(request, 'login.html', {})
        comments = comment_form.cleaned_data.get("comment")
        news_comment = NewsComments(user=request.user, comments=comments, news=news)
        news_comment.save()

    return render(request, "news_detail.html", {
        'title': title,
        'author': author,
        'add_time': add_time,
        'content': content,
        'tags': tags,
        'category': category,
        'all_comments': all_comments,
        'comment_form': comment_form
    })

Здесьмой шаблон news_detail, где я получаю данные формы:

{% if user.is_authenticated %}
<form id="js-pl-submit" method="POST" action="">{% csrf_token %}
{% for field in comment_form %}
{% for error in field.errors %}
<div class="alert alert-warning text-center mb-3" role="alert">{{ error }}</div>
{% endfor %}
{% endfor %}



Здесь, в моем шаблоне news_detail, я отображаю все комментарии к шаблону:

 {% for user_comments in all_comments %}
<img class="mr-3 comment-avatar rounded-circle"src="{{ MEDIA_URL }}{{ user_comments.user.image }}"alt="Generic placeholder image">
<div class="media-body">
<h6 class="mt-0 mb-1">{{ user_comments.user.username }}</h6>
{{ user_comments.comments }}
</div>
<span>{{ user_comments.add_time }}</span>
{% endfor %}

Вот мой Ajax в шаблоне news_detail:

$('#js-pl-submit').on('click', function(){
    var comments = $("#js-pl-textarea").val()
    if(comments == ""){
        alert("评论不能为空")
        return false
    }
    $.ajax({
        cache: false,
        type: "POST",
        url:"",
        data:{'news_pk':{{ news.id }}, 'comments':comments},
        async: true,
        beforeSend:function(xhr, settings){
            xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
        },
        success: function(data) {
            if(data.status == 'fail'){
                if(data.msg == '用户未登录'){
                    window.location.href="login";
                }else{
                    alert(data.msg)
                }
            }else if(data.status == 'success'){
                window.location.reload();//刷新当前页面.
            }
        },
    });
    return false;
});

Наконец, вот мой form.py комментария.

def words_validator(comment):
    if len(comment) < 4:
        raise ValidationError("亲,最少写两个字")


class CommentForm(forms.Form):
    comment = forms.CharField(widget=forms.Textarea(), validators=[words_validator])

Ответы [ 4 ]

0 голосов
/ 28 апреля 2018

Наконец-то я это сделал! Спасибо, Господи! Очень взволнован! Пожалуйста, проверьте мой подробный ответ здесь: Django Ajax Form отправьте неправильно перенаправить на другую страницу очень ценю ответ каждого! С вашим ответом я разобрался с этим вопросом шаг за шагом!

0 голосов
/ 25 апреля 2018

Ваша привязка неверна, у вас есть обработчик кликов в форме, он должен быть обработчиком отправки.Если бы вы привязывали его к кнопке, вы бы использовали обработчик click.

$('#js-pl-submit').on('submit', function(){//<-- here
    var comments = $("#js-pl-textarea").val()
    if(comments == ""){
        alert("评论不能为空")
        return false
    }
    $.ajax({
        cache: false,
        type: "POST",
        url:"",
        data:{'news_pk':{{ news.id }}, 'comments':comments},
        async: true,
        beforeSend:function(xhr, settings){
            xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
        },
        success: function(data) {
            if(data.status == 'fail'){
                if(data.msg == '用户未登录'){
                    window.location.href="login";
                }else{
                    alert(data.msg)
                }
            }else if(data.status == 'success'){
                window.location.reload();//刷新当前页面.
            }
        },
    });
    return false;
});
0 голосов
/ 25 апреля 2018

Это может сработать, оно содержит некоторые предложения из ваших кодов.

++ newsDetailView
++ в news_details.html
++ в тебе скрипты

views.py

def newsDetailView(request, news_pk):
    #news = News.objects.get(id=news_pk) No need to get the object like this anymore
    news = get_object_or_404(News,id=news_pk) #
    title = news.title
    author = news.author_name
    add_time = news.add_time
    content = news.content
    category = news.category
    tags = news.tag.annotate(news_count=Count('news'))

    comment_form = CommentForm(request.POST or None)
    if request.method == 'POST' and comment_form.is_valid():
        # if request.method == 'POST' and request.is_ajax() and comment_form.is_valid(): To make sure it's ajax
        if not request.user.is_authenticated:
            return JsonResponse({"msg":"You need to login",
            "url":'login_url','status':'login_required'})
        comments = comment_form.cleaned_data.get("comment")
        news_comment = NewsComments(user=request.user, comments=comments, news=news)
        news_comment.save()

    # This needs to be after request.POST process 
    all_comments = NewsComments.objects.filter(news=news) 

    context = {
        'title': title,
        'author': author,
        'add_time': add_time,
        'content': content,
        'tags': tags,
        'category': category,
        'all_comments': all_comments,
        'comment_form': comment_form,
    }   
    return render(request, "news_detail.html", context)

news_detail.html | Форма

{% if user.is_authenticated %}
<form id="js-pl-submit" method="POST" action="">{% csrf_token %}
    {% for field in comment_form %}
        {% for error in field.errors %}
        <div class="alert alert-warning text-center mb-3" role="alert">{{ error }}</div>
        {% endfor %}
    {% endfor %}
</form>
{% endif %}

news_detail.html | Комментарии

<div id="comments_section">
    {% for user_comments in all_comments %}
    <img class="mr-3 comment-avatar rounded-circle" src="{{ MEDIA_URL }}{{ user_comments.user.image }}" alt="Generic placeholder image">
    <div class="media-body">
        <h6 class="mt-0 mb-1">{{ user_comments.user.username }}</h6>
        {{ user_comments.comments }}
    </div>
    <span>{{ user_comments.add_time }}</span>
    {% endfor %}
</div>

JS скрипт

$(document).on('submit','#js-pl-submit',function(){ // Correction : Not click, but submit
    var comments = $("#js-pl-textarea").val()
    if(!comments){
        alert("评论不能为空")
        return false
    }
    $.ajax({
        cache: false,
        type: "POST",
        url:"",
        data:{
            // 'news_pk':{{ news.id }}, No need to send the news.id
            /// you are actually on the instance of `news` Object 
            'comments':comments,
            'csrfmiddlewaretoken':$("input[name=csrfmiddlewaretoken]").val(), // retrieve `csrf_token` from `form`
        },
        async: true,
        success: function(data) {
            // Not sure it's the more powerful, but this should work like a charm
            if(data.status == 'login_url'){
                alert(data.msg);
                window.location.href = data.url;
            }
            // Those 2 next lines are useful if you want to refresh without reload the page.
            $("#js-pl-submit").replaceWith($('#js-pl-submit',data));//刷新当前页面.
            $("#comments_section").replaceWith($('#comments_section',data));
            // This next line will reload the page
            windows.location.reload();

        },
        error:function(){
            // Codes here in case of error
        },
        statusCode:{
            404:function(){
                alert("Object not found");
            },
            500:function(){
                alert("An error has occured on the server");
            },
        }
    });
    return false;
});

Не стесняйтесь комментировать, чтобы я мог отредактировать свой ответ, чтобы помочь вам добиться успеха.

0 голосов
/ 25 апреля 2018

Добавьте событие клика на button, а не на form, и вы должны изменить его на button неявно. По умолчанию тип button передается.

<form method="POST" action="">
<button type="button" id="js-pl-submit"> 

Удалить id формы. Кнопка «Отправить» отправляет данные формы и обновляет страницу.

...