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

时间:2018-04-29 21:01:33

标签: python django python-3.x django-views django-urls

您好Djangonauts我是Django的新手请原谅我,如果我的代码中有愚蠢的错误,我正在尝试为我的帖子模型添加评论

以下是我的 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个视图中都获得了与以下相同的错误消息,并且还更改了网址

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

enter image description here

2 个答案:

答案 0 :(得分:1)

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

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

然后在你的app 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'),

然后,您添加新评论的网址将显示为http://127.0.0.1:8000/posts/add_comment/how-to-be-a-good-developer/。 URL的最后一部分是你的slug,你应该在你的数据库中有一个这个slug的帖子,因为如果你使用get_object_or_404函数并且你的任何帖子都没有被发送的slug你将获得404. / p>

如何在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值并检查你的数据库中是否有这个slug的帖子。

要检查的最后一件事。如果您将在控制台的This is my post: {post object}中看到,您知道Django选择了正确的帖子,问题出现在视图的下一个代码中(我不指望)。如果您在控制台中看到无对象或404或任何错误,您可能没有使用您在数据库中的URL中发送的slug的帖子。

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

答案 1 :(得分:1)

耶士!!!得到它了。我头上有几条绷带,墙上有几条裂缝,但我终于明白了。感谢@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)

哦,是的,但最不重要的是你的模板。下面是你添加评论按钮的方式。我相信很多聪明人都不会需要它。但是嘿,他们没有受伤!如果您没有使用bootstrap,请删除&#34;类&#34;来自锚标记

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