添加到帖子的评论:找不到页面 (404)

Posted

技术标签:

【中文标题】添加到帖子的评论:找不到页面 (404)【英文标题】:Adding to comments to post: Page not found (404) 【发布时间】:2018-10-10 00:04:24 【问题描述】:

嗨 Djangonauts 我是 Django 新手,如果我的代码中有愚蠢的错误,请原谅我,我目前正在尝试将 cmets 添加到我的帖子模型中

以下是我的 models.py

class Post(models.Model):
    user = models.ForeignKey(User, related_name='posts')
    title = models.CharField(max_length=250, unique=True)
    slug = models.SlugField(allow_unicode=True, unique=True)
    message = models.TextField()

    def get_absolute_url(self):
        return reverse('posts:single', kwargs='username': self.user.username, 'slug': self.slug) 

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super().save(*args, **kwargs)


class Comment(models.Model):
    post = models.ForeignKey(Post, related_name='comments')
    author = models.ForeignKey(User, related_name='comments')
    text = models.TextField()

    def get_absolute_url(self):
        return reverse('posts:single', kwargs='username': self.post.user.username,
                                               'slug': self.post.slug)

views.py 第一次尝试

@login_required
def add_comment_to_post(request, slug):
    post = get_object_or_404(Post, slug=slug)
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = post
            comment.author = request.user
            comment.save()
            return redirect('posts:single', username=comment.author.username, slug=post.slug)

    else:
        form = CommentForm()
        return render(request, 'posts/comment_form.html', 'form': form)


@login_required
def remove_comment(request, pk):
    comment = get_object_or_404(Comment, pk=pk)
    comment.author = request.user
    post_slug = comment.post.slug
    comment.delete()
    return redirect('posts:single', username=request.user.username, slug=post_slug)

urls.py

url(r'^(?P<slug>[-\w]+)/add_comment/$', views.CommentCreate.as_view(), name='add_comment'),

下面还有 FBV 的网址,它们都给了我同样的错误

url(r'^(?P<slug>[-\w]+)/add_comment/$', views.add_comment_to_post, name='add_comment'),
url(r'^(?P<pk>\d+)/remove_comment/$', views.remove_comment, name='remove_comment'),

Views.py 第二次尝试

class CommentCreate(LoginRequiredMixin, CreateView):
    model = Comment
    fields = ('text',)
    form_class = 'posts/comment_form.html'

    def form_valid(self, form, *args, **kwargs):
        self.object = form.save(commit=False)
        self.object.user = self.request.user
        slug = self.kwargs('slug')
        print(slug)
        self.object.post = get_object_or_404(Post, slug=slug)
        self.object.save()
        return super().form_valid(form)

views.py 第三次尝试

@login_required
def add_comment_to_post(request, slug):
    print(slug)
    post = get_object_or_404(Post, slug=slug)
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = post
            comment.author = request.user
            comment.save()
            return redirect('posts:single', username=comment.author.username, slug=post.slug)

    else:
        form = CommentForm()
        return render(request, 'posts/comment_form.html', 'form': form)

还将网址更改为

url(r'^add_comment/(?P<slug>[\w-]+)/$', views.add_comment_to_post, name='add_comment'),

下面是 PostDetail 视图和网址,它们完美运行

class PostDetail(SelectRelatedMixin, DetailView):
    model = Post
    select_related = ('user', 'group')

    def get_queryset(self):
        queryset = super().get_queryset()
        return queryset.filter(user__username__iexact=self.kwargs.get('username'))   
   #below is the url
 url(r'^(?P<username>[-\w]+)/(?P<slug>[-\w]+)/$', views.PostDetail.as_view(), name='single'),

我在所有 3 个视图中都收到了与以下相同的 错误消息,并且 URL 也已更改

Page not found (404)
Request Method: GET
Request URL:    http://127.0.0.1:8000/posts/...
Raised by:  posts.views.PostDetail

【问题讨论】:

在我看来更像是 urls.py 的问题。你能用 urls.py 编辑答案吗? @Bulva 如果您需要比我在问题中提供的更多信息,请告诉我。我添加了尽可能多的信息而没有让问题太长,但我很乐意提供任何可以帮助解决这个问题的信息 @Bulva 还添加了我在上述问题中使用的 url,并编辑了标签以包含 Django-urls 最好将 slug 和 pk 移到 url 的末尾。例如:url(r'^add_comment/(?P[\w-]+)/$', 'views.add_comment_to_post', name='add_comment')。然后,如果您在一个好的 url 上发送一个好的请求,那么您可能没有正确的 slug 的帖子。您可以在视图中使用 print() 来调试显示错误的位置。 例如在 post = get_object_or_404(Post, slug=slug) 之前添加 print(slug) 并检查 slug。如果您将在控制台中显示 slug,您就知道问题出在打印之后。如果您的控制台中没有 slug,您可能会在错误的 url 上发送请求。没有机会尝试所有代码,很难调试 【参考方案1】:

因此,我希望您的项目中有一个 urls.py,其中您的应用包含 urls.py(可能命名为帖子)。项目urls.py 可能看起来像这样:

(r'^posts/', include('project.posts.urls'))

然后在你的应用程序 urls.py 中你有你发送给我的内容:

url(r'^(?P<slug>[-\w]+)/add_comment/$', views.add_comment_to_post, name='add_comment'),
url(r'^(?P<pk>\d+)/remove_comment/$', views.remove_comment, name='remove_comment'),

我个人将其更改为 slug 和主键位于 URL 末尾的版本,如下所示:

url(r'^add_comment/(?P<slug>[-\w]+)/$', views.add_comment_to_post, name='add_comment')
url(r'^remove_comment/(?P<pk>\d+)/$', views.remove_comment, name='remove_comment'),

然后,您添加新评论的 URL 将类似于 http://127.0.0.1:8000/posts/add_comment/how-to-be-a-good-developer/。 URL 的最后一部分是您的 slug,您的数据库中应该有一个带有此 slug 的帖子,因为如果您使用get_object_or_404 函数并且您的任何帖子中的任何帖子都没有发送的 slug,您将得到 404。

如何在 Django 中轻松调试代码

您可能使用命令python manage.py runserver 从控制台(命令行)运行您的 Django 项目。在这个控制台中运行着一个小型开发服务器(与您可能知道的其他应用程序服务器非常相似)。如果将print() 语句添加到代码中,则输出将通过标准输出发送(在这种情况下,将发送到您启动开发服务器的控制台)。因此,如果您在一个好的 URL 上发送请求,您可以添加打印语句以轻松调试问题。试试这样的:

@login_required
def add_comment_to_post(request, slug):
    print('I am here in your view')
    print('This is my slug: '.format(slug))
    post = get_object_or_404(Post, slug=slug)
    print('This is my post: '.format(post))
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = post
            comment.author = request.user
            comment.save()
            return redirect('posts:single', username=comment.author.username, slug=post.slug)

    else:
        form = CommentForm()
        return render(request, 'posts/comment_form.html', 'form': form)

现在,如果您将在控制台中看到I am here in your view,则 Post 请求已成功解析并且视图正在运行。在这个时候你知道你的urls.py很好。

如果您将看到消息 This is my slug: your slug from url,您可以检查 slug 值并检查您的数据库中是否有 Post with this slug。

最后一件事要检查。如果您将在控制台中看到This is my post: post object,您就知道 Django 选择了正确的 Post 并且问题出在视图的下一个代码中(我没想到)。如果您在控制台中看到 None 对象或 404 或任何错误,则您可能没有在数据库中的 URL 中发送带有 slug 的 Post。

如果您有问题或想在控制台中讨论一些输出,您可以写评论 :-)

【讨论】:

是的,对不起。那是个错误。当然它应该看起来像第二个 url 函数。无字符串但查看函数 当我复制并粘贴您在上面给出的确切网址时,它会给我以下错误 **TypeError: view must be a callable or a list/tuple in the case of include()**you have views如果我这样做,在字符串"views.add_comment_to_post" 中。 url(r'^add_comment/(?P&lt;slug&gt;[\w-]+)/$', views.add_comment_to_post, name='add_comment'), 我再次得到 404。控制台中没有打印任何内容。我知道如何检查控制台。我有一个类似的类似帖子的视图,它在 slug 正在打印的代码中有一个print(slug)'I am here in your view' 也没有打印。我投了赞成票,但仍在试图找出问题所在 我在上图中的地址栏中添加了我的网址的外观。我认为网址是正确的 如果'I am here in your view' 也没有打印,这意味着什么。我想知道它是如何在不打印前 2 个打印命令的情况下到达 get 404 代码 这意味着url解析器没有找到正确的视图。错误中是posts.view.PostDetail。你的views.py中没有这个视图我认为所以如果在urls.py中找不到url,这必须是帖子的默认视图【参考方案2】:

是的!!!知道了。我的头上有几根绷带,墙上也有几处裂缝,但我终于搞定了。非常感谢@Bulva 为我指引正确的方向

urls.py 应该是

    url(r'^(?P<username>[-\w]+)/(?P<slug>[-\w]+)/add_comment/$', views.CommentCreate.as_view(), name='add_comment'),

因为我们既需要发布评论的人的用户名,也需要发布评论的帖子。上面的网址都有

views.py 应该如下

class CommentCreate(LoginRequiredMixin, CreateView):
    model = Comment
    form_class = CommentForm #In the second attempt above I used a template name. which is incorrect we should either use a formclass from forms.py or use "fields = text" 

    def form_valid(self, form, *args, **kwargs):
        self.object = form.save(commit=False)
        self.object.author = self.request.user #I used self.object.user instead of self.object.author. since the models call the "user" as "author". I changed this  
        slug = self.kwargs.get('slug') #I added the .get without which you get a "'dict' object is not callable" error 
        print(slug)
        self.object.post = get_object_or_404(Post, slug=slug)
        self.object.save()
        return super().form_valid(form)

哦,是的,最后但并非最不重要的是在您的模板中。下面是添加评论按钮的方法。我敢肯定,你们很多聪明人都不需要它。但是,嘿不疼对!如果您不使用引导程序,请从锚标记中删除“类”

<a class="btn btn-primary comment_button" href="% url 'posts:add_comment' username=post.user.username slug=post.slug %">Add Comment</a>

【讨论】:

以上是关于添加到帖子的评论:找不到页面 (404)的主要内容,如果未能解决你的问题,请参考以下文章

Rails 和 Api.ai 的“找不到 404 帖子”

如何拯救在rails中找不到404页面?

找不到页面(404):django无法匹配路径

Django:找不到页面(404)

NextJS 部署到 Vercel:找不到 404 页面

找不到错误:找不到页面(404)