【问题标题】:How to add comments on django如何在 django 上添加评论
【发布时间】:2020-05-19 20:06:20
【问题描述】:

我正在尝试向我的项目添加评论系统,所有代码看起来都很好,但我收到此错误“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',)

【问题讨论】:

  • 你能分享完整的回溯吗?
  • 同样__str__方法不对,把format方法参数改成self.post.title, str(self.user.username)
  • 这个视图有点奇怪,你列出了所有Post对象,但是当你发出POST请求来创建新评论时,你的视图不知道Post你是什么发表评论。
  • @DenizKaplan 在模型上修复了该问题并没有改变任何东西,您能否更好地向我解释一下我可以在视图上做什么或发布答案?
  • 我猜stackoverflow.com/a/61900155/2474573 这就是答案,如果您无法实现您的目标,请尝试使用您的回溯更新您的问题。

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


【解决方案1】:

在搜索了 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(它只显示 cmets)

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

【讨论】:

    【解决方案2】:

    您需要将单个 Post 传递给 cmets 的 create 数学,因为相应的字段是 ForeignKey 并且您正在传递整个查询集 (Post.objects.all())

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

    single_post = Post.objects.get(pk=the_post_pk)
    comment = Comment.objects.create(post=single_post, user=request.user, content=content)
    

    【讨论】:

    • 是的,我现在也看到get_object_or_404 是错误的,您需要一个额外的参数,请参阅docs
    【解决方案3】:

    问题是你写的:

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

    这里的images 是一组Post 对象,而不是单个Post 对象,因此您不能对其进行过滤。但实际上你确实不需要无论如何都需要这样做。

    此外,您的Comment 模型的__str__ 也有一个小错误:

    class Comment(models.Model):
        # …
    
        def __str__(self):
            return '{}-{}'.format(self.post.text, self.user.username)

    但是视图本身看起来很“奇怪”,因为你在这里写了一个Posts 的列表,但是如果你发出一个 POST 请求,你将不知何故需要知道你想向哪个帖子提交Comment,因此,至少接受 POST 请求的视图需要知道 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')
    ]

    在该视图中,我们可以获取项目,例如使用get_object_or_404,如果是POST,则在视图中设置postuser 对象:

    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)

    在您的模板中,您可以使用以下命令渲染帖子的 cmets:

    {{ 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-detail 视图发出 POST 请求。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-06
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 2021-01-07
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多