首页 > 解决方案 > Django jquery ajax 评论回复创建多个值

问题描述

我正在使用 django jquery 和 ajax 创建评论回复活动。它创建多个值来评论或回复博客。我该如何解决这个问题?提前致谢。 模型.py

class Comment(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    timestamp = models.DateTimeField(auto_now_add=True)
    content = models.TextField(max_length=1000)
    reply = models.ForeignKey('Comment', on_delete=models.CASCADE, related_name='replies', null=True, 
            blank=True, default=None)
    post = models.ForeignKey('Post', related_name='comments', on_delete=models.CASCADE)

    objects = models.Manager()

    class Meta: 
        ordering = ['-timestamp']

    def __str__(self):
        return self.user.username

表格.py

class CommentForm(forms.ModelForm):
    content = forms.CharField(widget=forms.Textarea(attrs={
        'class': 'form-control',
        'placeholder': 'Leave a comment!',
        'rows': '4'
    }))
    class Meta:
        model = Comment
        fields = ['content', ]

视图.py

def post_detail(request,slug):
post = get_object_or_404(Post, slug=slug)
comments = Comment.objects.filter(post=post, reply=None).order_by('-id')

is_liked = False
if post.likes.filter(id=request.user.id).exists():
    is_liked = True


if request.method=='POST':
    comment_form = CommentForm(request.POST or None)
    if comment_form.is_valid():
        content = request.POST.get('content')
        reply_id = request.POST.get('comment_id') #reply-section
        comment_qs = None
        if reply_id:
            comment_qs = Comment.objects.get(id=reply_id).exists()
        comment = Comment.objects.create(post=post, user=request.user, content=content, reply=comment_qs)
        comment.save()
else:
    comment_form = CommentForm()

context = {
    'post': post,
    'is_liked': is_liked,
    'comments': comments,
    'total_likes': post.likes.count(),
    'total_comments': post.comments.count(),
    'comment_form': comment_form,
}
if request.is_ajax():
    html = render_to_string('comment_section.html', context, request=request)
    return JsonResponse({'form': html})

return render(request, 'post_detail.html', context)

comment_section.html

{% extends "base.html" %}
{% block content %}
<div class="container-fluid mt-2">
<div class="form-group row">
  <form class="comment-form" method="post" action=".">
    {% csrf_token %}
    <div class="form-group">
      <textarea name="content" cols="60" rows="2" maxlength="1000" required="" id="id_content"></textarea>
    </div>
    <button type="submit" value="submit" class="btn-sm btn-outline-warning" style="color: black;">Comment</button>
  </form>
</div>
</div>
{% if not post.comments.all %}
<small>No comments to display</small>
{% endif %}
{% for comment in comments %}
<blockquote class="blockquote">
  <img style="float:left; clear: left;" class="rounded-circle article-img" height="10" width="10" 
src="#"><a href="#" style="text-decoration: none; color: black;"><h5>{{ 
comment.user.username|capfirst }}</h5></a>
  <p style="font-size: 8px;">{{ comment.timestamp }}</p>
  <p style="font-size: 14px;" class="mb-3">{{ comment.content }}</p>
  <a  type="button" name="button" class="reply-btn ml-4"><i class="fas fa-reply fa-sm"></i></a>&emsp;
  {% if request.user == comment.user %}
  <a href="#"><i class="fas fa-trash fa-sm" style="color: brown;"></i></a></td>
  {% endif %}
  </blockquote>
      {{ comment.replies.count }}
  <div class="replied-comments col-md-5" style="display: none;">
    {% for reply in comment.replies.all %}
    <blockquote class="blockquote">
      <img style="float:left; clear: left;" class="rounded-circle article-img" height="50" width="50" 
  src=""><a href="" style="text-decoration: none; color: black;"><h6>{{ reply.user.username|capfirst 
  }}</h6></a><br>
      <p style="font-size: 13px;" class="mb-3">{{ reply.content }}</p>
    </blockquote>
    {% endfor %}
    <div class="form-group row">
      <form class="reply-form" method="post" action=".">{% csrf_token %}
        <input type="hidden" name="comment_id" value="{{ comment.id }}">
        <div class="form-group">
          <textarea name="content" cols="60" rows="2" maxlength="1000" required="" id="id_content"> 
</textarea>
        </div>
        <input type="submit" value="submit" class="btn-sm btn-outline-light" style="color: black;">
      </form>
    </div>
  </div>
  {% endfor %}

{% endblock content %}

jQuery/ajax

$(document).on('submit', '.comment-form', function(event){
  event.preventDefault();
  console.log($(this).serialize());
  $.ajax({
    type: 'POST',
    url: $(this).attr('action'),
    data:$(this).serialize(),
    dataType: 'json',
    success: function(response) {
      $('.main-comment-section').html(response['form']);
      $('textarea').val('');
      $('.reply-btn').click(function() {
        $(this).parent().parent().next('.replied-comments').fadeToggle();
        $('textarea').val('');
      });
    },
    error: function(rs, e) {
      console.log(rs.responseText);
    }
  });
});

$(document).on('submit', '.reply-form', function(event){
  event.preventDefault();
  console.log($(this).serialize());
  $.ajax({
    type: 'POST',
    url: $(this).attr('action'),
    data:$(this).serialize(),
    dataType: 'json',
    success: function(response) {
      $('.main-comment-section').html(response['form']);
      $('textarea').val('');
      $('.reply-btn').click(function() {
        $(this).parent().parent().next('.replied-comments').fadeToggle();
        $('textarea').val('');
      });
    },
    error: function(rs, e) {
      console.log(rs.responseText);
    }
  });
});

为什么会出现这个错误?

MultipleObjectsReturned at … get() 返回了多个评论 - 它返回了 2

标签: jquerydjangoajax

解决方案


您的问题与以下行有关:

if reply_id:
    comment_qs = Comment.objects.get(id=reply_id).exists()

它返回2 个对象。您必须从数据库中删除重复项。

然后您可以使用以下两个代码之一。

第一种方法:如果CommentFormModelForm

... 

if request.method=='POST':
    querydict = request.POST
    comment_form = CommentForm(querydict)
    if comment_form.is_valid():
        comment = comment_form.save(commit=False)
        comment.post = post
        comment.user = request.user
        comment.reply_id = querydict.get('comment_id')
        comment.save()      
else:
    comment_form = CommentForm()
...

或作为第二种方法:如果您的表格不是ModelForm或其他原因

... 

if request.method=='POST':
    querydict = request.POST
    comment_form = CommentForm(querydict)
    if comment_form.is_valid():
        comment = Comment.objects.create(
            post=post, user=request.user, 
            content=querydict.get('content'), 
            reply_id=querydict.get('comment_id')
        )
        
else:
    comment_form = CommentForm()
...

在 Ajax 中,我还会禁用提交按钮:

var form = $(this);
form.find('input[type="submit"]').attr('disabled', true);

当 ajax 完成后启用:

complete: function (data) {
    form.find('input[type="submit"]').attr('disabled', false);
}

推荐阅读