Ajax 在 Django 帖子中不起作用 [英] Ajax not work in Django post

查看:16
本文介绍了Ajax 在 Django 帖子中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 Django 中使用 ajax 在新闻网站上发表评论.但是它不起作用.当我单击提交按钮时,它仍然刷新页面并且与没有 ajax 一样没有区别.

我真的是 Django 和 Ajax 的新手.有没有朋友可以帮我解决这个问题?

这是我的 view.py:

def newsDetailView(request, news_pk):新闻 = News.objects.get(id=news_pk)标题 = 新闻.标题作者 = news.author_nameadd_time = news.add_time内容 = 新闻.内容类别 = 新闻.类别标签 = news.tag.annotate(news_count=Count('news'))all_comments = NewsComments.objects.filter(news=news)comment_form = CommentForm(request.POST or None)如果 request.method == 'POST' 和 comment_form.is_valid():如果不是 request.user.is_authenticated:返回渲染(请求,'login.html',{})评论 = comment_form.cleaned_data.get("评论")news_comment = NewsComments(user=request.user,comments=comments,news=news)news_comment.save()返回渲染(请求,news_detail.html",{'标题':标题,'作者':作者,'添加时间':添加时间,'内容':内容,标签":标签,类别":类别,'all_comments': all_comments,'comment_form':comment_form})

这是我获取表单数据的 news_detail 模板:

{% if user.is_authenticated %}<form id="js-pl-submit" method="POST" action="">{% csrf_token %}{% 用于 comment_form 中的字段 %}{% for error in field.errors %}<div class="alert alert-warning text-center mb-3" role="alert">{{ error }}</div>{% 结束为 %}{% 结束为 %}



在我的 news_detail 模板中,我将所有评论渲染到模板中:

 {% for user_comments in all_comments %}<img class="mr-3 comment-avatar rounded-circle"src="{{ MEDIA_URL }}{{ user_comments.user.image }}"alt="通用占位符图片"><div class="media-body"><h6 class="mt-0 mb-1">{{ user_comments.user.username }}</h6>{{ user_comments.comments }}

<span>{{ user_comments.add_time }}</span>{% 结束为 %}

这是我在 news_detail 模板中的 Ajax:

$('#js-pl-submit').on('click', function(){var 评论 = $("#js-pl-textarea").val()如果(评论=="){alert("评论不能为空")返回假}$.ajax({缓存:假,类型:POST",网址:"",数据:{'news_pk':{{ news.id }}, 'comments':comments},异步:真,beforeSend:函数(xhr,设置){xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");},成功:功能(数据){if(data.status == 'fail'){if(data.msg == '用户未登录'){window.location.href="登录";}别的{警报(数据.msg)}}else if(data.status == 'success'){window.location.reload();//刷新当前页面.}},});返回假;});

最后是我的评论的 form.py.

def words_validator(评论):如果 len(comment) <4:raise ValidationError("亲,最少写两个字")类 CommentForm(forms.Form):评论 = forms.CharField(widget=forms.Textarea(),validators=[words_validator])

解决方案

这可行,它包含来自您的代码的一些建议.

<块引用>

++ 新闻细节视图
++ 在 news_details.html
++ 在你的脚本中

views.py

def newsDetailView(request, news_pk):#news = News.objects.get(id=news_pk) 不需要再像这样获取对象了新闻 = get_object_or_404(News,id=news_pk) #标题 = 新闻.标题作者 = news.author_nameadd_time = news.add_time内容 = 新闻.内容类别 = 新闻.类别标签 = news.tag.annotate(news_count=Count('news'))comment_form = CommentForm(request.POST or None)如果 request.method == 'POST' 和 comment_form.is_valid():# if request.method == 'POST' and request.is_ajax() and comment_form.is_valid(): 确保是ajax如果不是 request.user.is_authenticated:return JsonResponse({"msg":"您需要登录","url":'login_url','status':'login_required'})评论 = comment_form.cleaned_data.get("评论")news_comment = NewsComments(user=request.user,comments=comments,news=news)news_comment.save()# 这需要在request.POST 过程之后all_comments = NewsComments.objects.filter(news=news)上下文 = {'标题':标题,'作者':作者,'添加时间':添加时间,'内容':内容,标签":标签,类别":类别,'all_comments': all_comments,'comment_form':comment_form,}返回渲染(请求,news_detail.html",上下文)

news_detail.html |表格

{% if user.is_authenticated %}<form id="js-pl-submit" method="POST" action="">{% csrf_token %}{% 用于 comment_form 中的字段 %}{% for error in field.errors %}<div class="alert alert-warning text-center mb-3" role="alert">{{ error }}</div>{% 结束为 %}{% 结束为 %}</表单>{% 万一 %}

news_detail.html |评论

{% for user_comments in all_comments %}<img class="mr-3 comment-avatar rounded-circle" src="{{ MEDIA_URL }}{{ user_comments.user.image }}" alt="通用占位符图片"><div class="media-body"><h6 class="mt-0 mb-1">{{ user_comments.user.username }}</h6>{{ user_comments.comments }}

<span>{{ user_comments.add_time }}</span>{% 结束为 %}

JS 脚本

$(document).on('submit','#js-pl-submit',function(){//更正:不是点击,而是提交var 评论 = $("#js-pl-textarea").val()如果(!评论){alert("评论不能为空")返回假}$.ajax({缓存:假,类型:POST",网址:"",数据:{//'news_pk':{{ news.id }}, 不需要发送news.id///你实际上是在`news`对象的实例上'评论':评论,'csrfmiddlewaretoken':$("input[name=csrfmiddlewaretoken]").val(),//从 `form` 中检索 `csrf_token`},异步:真,成功:功能(数据){//不确定它更强大,但这应该像一个魅力if(data.status == 'login_url'){警报(数据.味精);window.location.href = data.url;}//如果您想在不重新加载页面的情况下刷新,那么接下来的 2 行很有用.$("#js-pl-submit").replaceWith($('#js-pl-submit',data));//刷新当前页面.$("#comments_section").replaceWith($('#comments_section',data));//下一行将重新加载页面windows.location.reload();},错误:函数(){//出现错误时的代码},状态代码:{404:功能(){alert("找不到对象");},500:功能(){alert("服务器发生错误");},}});返回假;});

随时发表评论,以便我可以编辑我的答案,以帮助您成功.

I'm trying to use ajax in Django to post comment in a news website.However it doesn't work.When I click the submit button,it still refreshes the page and make no difference like no ajax.

I'm really new in Django and Ajax.Any friend can help me solve it?

Here is my 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
    })

Here is my news_detail template where I get form data:

{% 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 %}



Here in my news_detail template I render all the comments to the template:

 {% 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 %}

Here is my Ajax in news_detail template:

$('#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;
});

Finally here is my form.py of the comment.

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


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

解决方案

This could work, it contains some suggestions from your codes.

++ newsDetailView
++ in news_details.html
++ in you scripts

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 | Form

{% 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 | Comments

<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 script

$(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;
});

Feel free to comment, so that I can edit my answer, to help you succeed.

这篇关于Ajax 在 Django 帖子中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆