Hi Djangonauts I am new to Django please forgive me if I have silly mistakes in my code and I am currently trying to add comments to my post model
你好,Djangonauts,我是Django的新手,如果我的代码中有一些愚蠢的错误,请原谅我,我正在尝试给我的post模型添加注释
below are my models.py
下面是我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 1st attempt
的观点。py 1日尝试
@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
urls . py
url(r'^(?P<slug>[-\w]+)/add_comment/$', views.CommentCreate.as_view(), name='add_comment'),
Also I have the urls for FBV below they both give me the same error
下面还有FBV的url它们都给了我相同的错误
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 2nd attempt
的观点。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 3rd try
的观点。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})
also changed the urls to
还将url更改为。
url(r'^add_comment/(?P<slug>[\w-]+)/$', views.add_comment_to_post, name='add_comment'),
below is the PostDetail view and url they work perfect
下面是PostDetail视图和它们工作的url
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'),
I get the same error message as below in all 3 views and also with changed url
在所有的3个视图中,我都会得到与下面相同的错误消息,并使用已更改的url
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/posts/...
Raised by: posts.views.PostDetail
2 个解决方案
#1
1
So I expect you have a urls.py
in your projects where you included urls.py
for your app (probably named posts). Project urls.py
probably will look something like this:
我希望你有一个url。在项目中包含url的py。py为您的应用程序(可能命名为posts)。项目的url。py可能看起来是这样的:
(r'^posts/', include('project.posts.urls'))
Then in your app urls.py you have what have you send to me:
然后在你的app url中。你有什么东西要寄给我:
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'),
I personally this changed to version where slug and primary key will be in the end of the URL, like this:
我个人把它改成了这样的版本,在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'),
Then your URL for adding a new comment will look like http://127.0.0.1:8000/posts/add_comment/how-to-be-a-good-developer/
. The last part of the URL is your slug and you should have a Post with this slug in your database because if you useget_object_or_404
function and any of your Posts in your will not have the sended slug you will get 404.
然后,添加新注释的URL将类似于http://127.0.1:8000 /posts/add_comment/how to be a good developer/。URL的最后一部分是你的slug你应该在你的数据库中有一个带有这个slug的帖子,因为如果你使用get_object_or_404函数,你的任何一个帖子都不会有发送段,你就会得到404。
How to very easily debug your code in Django
如何很容易地调试Django中的代码
You probably run your Django project from console (command-line) with command python manage.py runserver
. In this console is running a little development server (very same as the others application servers you probably know). If you add print()
statement to your code, then the output will be send on standard output (in this case to your console where you started development server). So if you send a request on a good URL you can add print statements to easily debug problem. Try something like this:
您可能使用命令python管理从控制台(命令行)运行Django项目。py runserver。在这个控制台中运行一个小的开发服务器(与您可能知道的其他应用程序服务器非常相似)。如果将print()语句添加到代码中,那么输出将发送到标准输出(在本例中,输出将发送到开始开发服务器的控制台)。因此,如果您在一个好的URL上发送请求,您可以添加print语句以方便地调试问题。试试这样:
@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})
Now if you will see in your console I am here in your view
the Post request was successfully resolved and the view was running. In this time you know that yours urls.py
are good.
现在,如果你在控制台看到我在你的视图中,Post请求被成功解析,视图正在运行。此时,您就知道您的url了。py是好的。
If you will see the message This is my slug: {your slug from url}
you can check the slug value and check if in your database you have Post with this slug.
如果您将看到消息,这是我的slug:{您的slug from url},您可以检查slug值,并检查您的数据库中是否有带有该slug的帖子。
The last thing to check. If you will see in This is my post: {post object}
in your console you know that the Django select the right Post and the problem is in the next code of the view (which I don't expect). If you will see None object or 404 or any error in your console you probably haven't the Post with the slug you sent in your URL in the database.
最后要检查的。如果您在这里看到的是我的post: {post object}在您的控制台中,您知道Django选择了正确的post,问题在视图的下一个代码中(我不希望这样)。如果您在控制台中看不到任何对象或404或任何错误,那么您可能没有在数据库中发送URL的段塞。
If you will have questions or you will want discuss some outputs in the console you can write a comment :-)
如果你有问题或你想在控制台讨论一些输出,你可以写一个评论:
#2
1
Yess!!! got it. There are a few bandages on my head and few cracks on the wall but I finally got it.Thanks a lot to @Bulva for guiding me in the right direction
是的! ! !明白了。我头上有几条绷带,墙上有几条裂缝,但我终于找到了。非常感谢@Bulva为我指明了正确的方向
The urls.py should be
url。py应该
url(r'^(?P<username>[-\w]+)/(?P<slug>[-\w]+)/add_comment/$', views.CommentCreate.as_view(), name='add_comment'),
Since we need both the username of the person posting the comment and also the post where the comment has to be posted. The above url has both
因为我们既需要发布评论的用户名,也需要发布评论的用户名。上面的url两者都有
The views.py should be as below
视图。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)
Oh yeah last but not the least in your templates. below is how you add the comment button. I'm sure a lot of you smart guys won't need it. but hey doesn't hurt right!!. If you are not using bootstrap remove the "class" from the anchor tag
是的,最后但不是最不重要的在你的模板。下面是如何添加注释按钮。我相信你们很多聪明人都不需要它。但是,嘿,你没受伤吧!!如果不使用bootstrap,则从锚标记中删除“类”
<a class="btn btn-primary comment_button" href="{% url 'posts:add_comment' username=post.user.username slug=post.slug %}">Add Comment</a>
#1
1
So I expect you have a urls.py
in your projects where you included urls.py
for your app (probably named posts). Project urls.py
probably will look something like this:
我希望你有一个url。在项目中包含url的py。py为您的应用程序(可能命名为posts)。项目的url。py可能看起来是这样的:
(r'^posts/', include('project.posts.urls'))
Then in your app urls.py you have what have you send to me:
然后在你的app url中。你有什么东西要寄给我:
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'),
I personally this changed to version where slug and primary key will be in the end of the URL, like this:
我个人把它改成了这样的版本,在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'),
Then your URL for adding a new comment will look like http://127.0.0.1:8000/posts/add_comment/how-to-be-a-good-developer/
. The last part of the URL is your slug and you should have a Post with this slug in your database because if you useget_object_or_404
function and any of your Posts in your will not have the sended slug you will get 404.
然后,添加新注释的URL将类似于http://127.0.1:8000 /posts/add_comment/how to be a good developer/。URL的最后一部分是你的slug你应该在你的数据库中有一个带有这个slug的帖子,因为如果你使用get_object_or_404函数,你的任何一个帖子都不会有发送段,你就会得到404。
How to very easily debug your code in Django
如何很容易地调试Django中的代码
You probably run your Django project from console (command-line) with command python manage.py runserver
. In this console is running a little development server (very same as the others application servers you probably know). If you add print()
statement to your code, then the output will be send on standard output (in this case to your console where you started development server). So if you send a request on a good URL you can add print statements to easily debug problem. Try something like this:
您可能使用命令python管理从控制台(命令行)运行Django项目。py runserver。在这个控制台中运行一个小的开发服务器(与您可能知道的其他应用程序服务器非常相似)。如果将print()语句添加到代码中,那么输出将发送到标准输出(在本例中,输出将发送到开始开发服务器的控制台)。因此,如果您在一个好的URL上发送请求,您可以添加print语句以方便地调试问题。试试这样:
@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})
Now if you will see in your console I am here in your view
the Post request was successfully resolved and the view was running. In this time you know that yours urls.py
are good.
现在,如果你在控制台看到我在你的视图中,Post请求被成功解析,视图正在运行。此时,您就知道您的url了。py是好的。
If you will see the message This is my slug: {your slug from url}
you can check the slug value and check if in your database you have Post with this slug.
如果您将看到消息,这是我的slug:{您的slug from url},您可以检查slug值,并检查您的数据库中是否有带有该slug的帖子。
The last thing to check. If you will see in This is my post: {post object}
in your console you know that the Django select the right Post and the problem is in the next code of the view (which I don't expect). If you will see None object or 404 or any error in your console you probably haven't the Post with the slug you sent in your URL in the database.
最后要检查的。如果您在这里看到的是我的post: {post object}在您的控制台中,您知道Django选择了正确的post,问题在视图的下一个代码中(我不希望这样)。如果您在控制台中看不到任何对象或404或任何错误,那么您可能没有在数据库中发送URL的段塞。
If you will have questions or you will want discuss some outputs in the console you can write a comment :-)
如果你有问题或你想在控制台讨论一些输出,你可以写一个评论:
#2
1
Yess!!! got it. There are a few bandages on my head and few cracks on the wall but I finally got it.Thanks a lot to @Bulva for guiding me in the right direction
是的! ! !明白了。我头上有几条绷带,墙上有几条裂缝,但我终于找到了。非常感谢@Bulva为我指明了正确的方向
The urls.py should be
url。py应该
url(r'^(?P<username>[-\w]+)/(?P<slug>[-\w]+)/add_comment/$', views.CommentCreate.as_view(), name='add_comment'),
Since we need both the username of the person posting the comment and also the post where the comment has to be posted. The above url has both
因为我们既需要发布评论的用户名,也需要发布评论的用户名。上面的url两者都有
The views.py should be as below
视图。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)
Oh yeah last but not the least in your templates. below is how you add the comment button. I'm sure a lot of you smart guys won't need it. but hey doesn't hurt right!!. If you are not using bootstrap remove the "class" from the anchor tag
是的,最后但不是最不重要的在你的模板。下面是如何添加注释按钮。我相信你们很多聪明人都不需要它。但是,嘿,你没受伤吧!!如果不使用bootstrap,则从锚标记中删除“类”
<a class="btn btn-primary comment_button" href="{% url 'posts:add_comment' username=post.user.username slug=post.slug %}">Add Comment</a>