如何在Django上添加评论

时间:2020-05-19 20:06:20

标签: python django django-models django-forms django-views

我正在尝试向我的项目中添加注释系统,所有代码看起来都不错,但出现此错误“ ValueError at / 精确查找的QuerySet值必须限制为使用切片的一个结果。”我不知道出了什么问题,但是错误可能出在views.py文件上。

views.py

    def imagelist(request):
        images = Post.objects.all()
        post = get_object_or_404(Post)
        comments = Comment.objects.filter(post=images)
        if request.method == 'POST':
          comment_form = CommentForm(request.POST or None)
          if comment_form.is_valid():
            contentt = request.POST.get('content')
            comment = Comment.objects.create(post=images, user=request.user, content=content)
            comment.save()
            return HttpResponseRedirect(post.get_absolute_url())
        else:
          comment_form = CommentForm()
        context2 = {
            "images": images,
            "comments": comments,
            "comment_form": comment_form,
        }
return render(request, 'imagelist.html', context2)

models.py

    class Comment(models.Model):
        post = models.ForeignKey(Post, on_delete=models.CASCADE)
        user = models.ForeignKey(User, on_delete=models.CASCADE)
        content = models.TextField(max_length=160)
        timestamp = models.DateTimeField(auto_now_add=True)

        def __str__(self):
            return '{}-{}'.format(self.post.title.str(self.user.username))

    class Post(models.Model):
        text = models.CharField(max_length=200)
        posti = models.ImageField(upload_to='media/images', null=True, blank="True")
        video = models.FileField(upload_to='media/images', null=True, blank="True")
        user = models.ForeignKey(User, related_name='imageuser', on_delete=models.CASCADE, default='username')
        liked = models.ManyToManyField(User, default=None, blank=True, related_name='liked')
        updated = models.DateTimeField(auto_now=True)
        created =models.DateTimeField(auto_now_add=True)

        def __str__(self):
            return str(self.tittle)

forms.py

    class CommentForm(forms.ModelForm):
        class Meta:
            model = Comment
            fields = ('content',)

3 个答案:

答案 0 :(得分:1)

您需要将.bg-light的注释传递给create,因为相应的字段是Post,并且您要传递整个查询集(ForeignKey

您只需要获得评论所在的帖子即可。

Post.objects.all()

答案 1 :(得分:1)

问题是您写了:

images = Post.objects.all()
comments = Comment.objects.filter(post=images)

此处images是一组Post对象,而不是单个Post对象,因此您不能对此进行过滤。但是您实际上确实不需要仍然需要这样做。

此外,您的__str__模型的Comment中还存在一个小错误:

class Comment(models.Model):
    # …

    def __str__(self):
        return '{}-{}'.format(self.post.text, self.user.username)

但是视图本身看起来很“奇怪”,因为您在此处编写了Post的列表,但是如果您发出POST请求,则将需要以某种方式知道要提交{{ 1}},因此至少接受POST请求的视图将需要知道Comment的主键才能发表评论。例如,您可以在Post中进行编码:

urls.py

在该视图中,我们可以例如使用# appname/urls.py from django.urls import path from app import views urlpatterns = [ path('post/<int:pk>/', views.post_detail, name='post_detail'), path('post/', views.post_list, name='post_detail') ]来获取项目,并且在POST的情况下,在视图中设置get_object_or_404post对象:

user

在模板中,您可以使用以下方式呈现帖子的评论:

from django.shortcuts import redirect, get_object_or_404
from django.contrib.auth.decorators import login_required

@login_required
def post_detail(request, pk):
    image = get_object_or_404(Post, pk=pk)
    if request.method == 'POST':
          comment_form = CommentForm(request.POST, request.FILES)
          if comment_form.is_valid():
            comment_form.instance.user = request.user
            comment_form.instance.post = image
            comment_form.save()
            return redirect(post)
    else:
        comment_form = CommentForm()
    context = {
        'post': image,
        'comment_form': comment_form,
    }
    return render(request, 'imagedetail.html', context)

您还可以创建一个呈现列表的视图:

{{ post }}
{% for comment in post.comment_set.all %}
    {{ comment }}
{% endfor %}
<form method="post" action="{% url 'post_detail' pk=post.pk %}">
    {% csrf_token %}
    {{ comment_form }}
</form>

在列表模板中,您可以使用以下方式呈现它:

@login_required
def post_list(request, pk):
    images = Post.objects.prefetch_related('comment_set')
    comment_form = CommentForm()
    context = {
        'image': images,
        'comment_form': comment_form,
    }
    return render(request, 'imagelist.html', context)

因此,我们在此向{% for post in images %} {{ post }} {% for comment in post.comment_set.all %} {{ comment }} {% endfor %} <form method="post" action="{% url 'post-detail' pk=post.pk %}"> {% csrf_token %} {{ comment_form }} </form> {% endfor %}视图发出POST请求。

答案 2 :(得分:0)

在寻找答案的4个小时之后,这就是我的方法。我所做的就是添加此新视图,方法,URL和html。希望这会有所帮助!

views.py

     def imagedetail(request, pk):
       post = get_object_or_404(Post, pk=pk)
       comments = Comment.objects.filter(post=post)
       if request.method == 'POST':
         comment_form = CommentForm(request.POST or None)
         if comment_form.is_valid():
           content = request.POST.get('content')
           comment = Comment.objects.create(post=post, user=request.user, content=content)
           comment.save()
           return HttpResponseRedirect(post.get_absolute_url())

       else:
         comment_form = CommentForm()
       context2 = {
          "comments": comments,
          "comment_form": comment_form,
       }
       return render(request, 'imagedetail.html', context2)

models.py(在Post模型上)

    def get_absolute_url(self):
        return reverse('imagedetail', args=[self.id])

urls.py(用于imagedetail的新视图)

    path('imagedetail/<int:pk>/', views.imagedetail, name='imagedetail'),

imagelist.html(要重定向到imagedetail,顺便说一句,它是一个引导按钮)

    <a role="button" class="btn btn-primary" href="{% url 'imagedetail' pk=image.pk %}"></a>

imagedetail.html(仅显示评论)

    <form method="post">
      {% csrf_token %}
      {{comment_form.as_p}}
      {% if request.user.is_authenticated %}
        <input type="submit" value="Submit" class="btn btn-outline-succes">
      {% else %}
        <input type="submit" value="Submit" class="btn btn-outline-succes" disabled>
      {% endif %}
    </form>
    <div class="main-comment-section">
      {{ comments.count }}
      {% for comment in comments %}
        <blockquote class="blockquote">
            <p class="mb-0">{{ comment.content }}</p>
            <footer class="blockquote-footer">by <cite title="Source Title">{{ comment.user }}</cite></footer>
        </blockquote>
      {% endfor %}
    </div>