Django: "No comment found matching the query" 404 Error - python

I'm making a simple blog app with comments on a 'posts detail view' page, but I'm getting a 404 error saying "No comment found matching the query" whenever I try submitting my comment. Everything else in the app works except for the comments. I'm new to django and am making this site to learn, would appreciate any help!
Views.py
class PostDetailView(DetailView):
model = Post
fields = ['content']
class CommentCreateView(LoginRequiredMixin, CreateView):
model = Comment
fields = ['content']
template_name = 'blog/comment.html'
def form_valid(self, form):
post = self.get_object()
form.instance.author = self.request.user
return super().form_valid(form)
models.py
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(User, on_delete=models.CASCADE)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
class Meta:
ordering = ['-date_posted']
def __str__(self):
return f'Comment {self.content} by {self.author.username}'
def get_absolute_url(self):
return reverse('comment', kwargs={'pk': self.pk})
urls.py
from django.urls import path
from .views import (
PostListView,
PostDetailView,
PostCreateView,
PostUpdateView,
PostDeleteView,
UserPostListView,
CommentCreateView
)
from . import views
urlpatterns = [
path('', PostListView.as_view(), name='blog-home'),
path('post/comment/<int:pk>/', CommentCreateView.as_view(), name='create'),
path('user/<str:username>', UserPostListView.as_view(), name='user-posts'),
path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),
path('post/new/', PostCreateView.as_view(), name='post-create'),
path('post/<int:pk>/update/', PostUpdateView.as_view(), name='post-update'),
path('post/<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete'),
path('about/', views.about, name='blog-about'),
]
comments.html This is the form. It's supposed to redirect to a different form to comment then back to post detail view
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Comment</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Post</button>
</div>
</form>
</div>
{% endblock content %}

Related

Error when clicking like button in Django

I'm trying to add a like button to a blog post in Django, but I see this error every time I try to click in the like button. But if I opened the admin page then return to the site, it works properly, and I don't know why that is. Any help please?
The error I'm getting:
TypeError at /like/45 Field 'id' expected a number but got <SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x000001BF06424F10>>
views code:
def LikeView(request,pk):
post = get_object_or_404(Post, id=request.POST.get('post_id'))
post.likes.add(request.user)
models code:
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
likes= models.ManyToManyField(User,related_name='blog_post')
def total_likes(self):
return self.likes.count()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail',kwargs={'pk':self.pk})
urls:
urlpatterns = [
path('', PostListView.as_view(), name='blog-home'),
path('user/<str:username>', UserPostListView.as_view(), name='user-posts'),
path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),
path('post/new/', PostCreateView.as_view(), name='post-create'),
path('post/<int:pk>/update/', PostUpdateView.as_view(), name='post-update'),
path('post/<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete'),
path('about/', views.About, name='blog-about'),
path('like/<int:pk>',LikeView,name='like_post'),
]
The button in the template:
<form action="{% url 'like_post' post.pk %}" , method="POST">
{% csrf_token %}
<button
type="submit"
,
name="post_id"
,
value="{{ post.id }}"
,
class="btn btn-primary btn-ms"
>
Like
</button>

Django blog app with comments using class views

I' wanted to try Django framework and i tried the blog app tutorial. i tried to add a comment feature. i know these questions have been asked several times but couldn't find a solution to my problem.
I got the following error:
No Post matches the given query.
Thanks for your help. Here are the Model and all:
urls.py :
path('', PostListView.as_view(), name='blog-home'),
path('user/<str:username>/', UserPostListView.as_view(), name='user-posts'),
path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),
path('post/new/', PostCreateView.as_view(), name='post-create'),
path('post/<int:pk>/update/', PostUpdateView.as_view(), name='post-update'),
path('post/<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete'),
path('post/<int:pk>/comment/', PostCommentView.as_view(), name='post-comment'),
path('about/', views.about, name='blog-about'),
]
models.py:
class Post(models.Model):
title = models.CharField(max_length=50)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE) # many to one relation use foreign key
def __str__(self):
return self.title
#property
def get_comments(self):
return self.comment_content.all()
# return the url as string
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
class Comment(models.Model):
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, related_name='comment_content', on_delete=models.CASCADE)
def __str__(self):
return self.content
def get_absolute_url(self):
return reverse('comment-create', kwargs={'pk': self.pk})
forms.py:
class CommentForm(forms.ModelForm):
content=forms.Textarea()
class Meta:
model = Comment
fields=['content']
views.py:
class PostCommentView(LoginRequiredMixin, CreateView):
model = Comment
fields = ['content']
template_name = 'blog/comment_form.html'
success_url = '/'
def form_valid(self, form):
post = get_object_or_404(Post, id=self.kwargs.get('id'))
print(post.id)
form.instance.author = self.request.user
form.instance.post = post
return super().form_valid(form)
comment_form.htlm:
{% extends "blog/base.html" %}
{% load crispy_forms_filters %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Comment tag</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Post comment</button>
</div>
</form>
<div class="border-top pt-3">
<small class="text-muted">
Abort the Comment? <a class="ml-2" href="{% url 'blog-home' %}">Back to Main Page</a>
</small>
</div>
</div>
{% endblock content %}
'id' is standard primary key of a Django Model but not of the POST that is created with ModelForm etc.
I suppose you need to put a hidden field "id" in your form to get it sent with the POST request.
Try print(self.kwargs.get('id')) before the 'get_object...' and you will see if 'id' has some content.

How to pass the id of one class object to another class object in django views.py

This is for a library management web app, I need to filter a specific book object by it's id from a BookIssue object and make it as ISSUED when I click on issue button.
Here Post model have details of book and BookIssue have details of Library Member to borrow book.
When I click on Issue in html, it will go class BookIssueView, fromviews.py I need to change the value of issued field of Post model to True
See post = Post.objects.filter(id=self.request.GET.get('id')).update(issued=True) in views.py
Here I need to get the specific book that I selected by it's id.
How can I implement it?
models.py
class Post(models.Model):
title = models.CharField(max_length=100)
book_author = models.CharField(default="",max_length=100)
publisher = models.CharField(default="",max_length=100)
content = models.TextField(max_length=200)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
issued = models.BooleanField(default=False)
issued_to = models.CharField(default="",max_length=100,null=False)
issue_to_phone_number = models.CharField(default="",max_length=10)
def __str__(self):
return [self.title,self.id]
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk' : self.pk})
class BookIssue(models.Model):
issue_name = models.CharField(max_length=100,null=False)
issue_email = models.EmailField(max_length=254)
issue_phone_number = models.CharField(default="",max_length=10)
issue_address = models.TextField(max_length=300)
issued_book = models.ManyToManyField(Post,default="")
def __str__(self):
return self.issue_name
def get_absolute_url(self):
return reverse('blog-home')
views.py
class BookIssueView(LoginRequiredMixin,CreateView,Post):
model = BookIssue
fields = ['issue_name','issue_email','issue_phone_number','issue_address']
def form_valid(self, form):
post = Post.objects.filter(id=self.request.GET.get('id')).update(issued=True)
form.instance.author = self.request.user
return super().form_valid(form)
Template
bookissue_form.html
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="post">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Issue Book</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-success" type="submit" name="button">Issue</button>
<button class="btn btn-danger" type="submit" name="button">Cancel</button>
</div>
</form>
</div>
{% endblock %}
urls.py
from django.urls import path
from . import views
from .views import (PostListView,
PostDetailView,
PostCreateView,
PostUpdateView,
PostDeleteView,
BookIssueView,
BookReturnView)
urlpatterns = [
# path('',views.home, name='blog-home'),
path('',PostListView.as_view(), name='blog-home'),
path('post/<int:pk>/',PostDetailView.as_view(), name='post-detail'),
path('post/new/',PostCreateView.as_view(), name='post-create'),
path('post/<int:pk>/update/',PostUpdateView.as_view(), name='post-update'),
path('post/<int:pk>/delete/',PostDeleteView.as_view(), name='post-delete'),
path('post/<int:pk>/issue/',BookIssueView.as_view(), name='book-issue'),
path('post/<int:pk>/return/',BookReturnView.as_view(), name='book-return'),
path('about/',views.about, name='blog-about'),
]
The id is not in request.GET, it is in the pk kwarg of the URL.
Also, you don't seem to be doing anything to associate the Post with the BookIssue.
post = Post.objects.get(id=self.kwargs["pk"])
post.issued=True
post.save()
response = super().form_valid(form)
form.instance.issued_book.add(post)
return response

No Post matches the given query.in django

am using django 2.0 and here is the problem
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/blog/post-detail/
Raised by: blog.views.post_detail
No Post matches the given query.
here is the blog/urls
from django.urls import path,include
from .import views
urlpatterns = [
path('blog/',views.post_list,name="post_list"),
path('blog/post-detail/',views.post_detail,name="post_detail"),
]
and views.py
from django.shortcuts import render,get_object_or_404
from.models import Post
# Create your views here.
def post_list(request):
object_list=Post.objects.all()
context={
'object_list': object_list,
}
return render(request,"blog.html",context)
def post_detail(request,slug=None):
post=get_object_or_404(Post,slug=slug)
context={
'post':post,
}
return render(request,"post_detail.html",context)
and the post_detail.html
{% extends "base.html" %}
{% load static %}
{% block seo_title %}{% endblock %}
{% block seo_description %}{% endblock %}
{% block Content %}
<article>
<div class="embed-responsive embed-responsive-16by9">
<img src="images/blog1.jpg" alt="" />
</div>
<div class="post-content">
<h2>{{post.title}}</h2>
<div>
{{post.created}} Author {{Post.user}}
<hr/>
<p>{{post.body}}</p>
</article>
{% endblock Content %}
CAN ANYONE HELP ON THIS THE ONLY PROBLEM I SEE THAT SLUG THING I MUST HAVE CONFUSED SOMEWHERE
blog.html
<!-- Blog -->
<div class="blog">
<div class="row">
<div class="col-sm-8">
<!-- Blog Post-->
{% for obj in object_list %}
{% if obj.status == 'Published' %}
<article>
<div class="embed-responsive embed-responsive-16by9">
<img src="images/blog1.jpg" alt="" />
</div>
<div class="post-content">
<h2>{{obj.title}}</h2>
<div>
{{obj.created}} Author {{obj.user}}
<hr/>
<p>{{obj.body}}</p>
<a class="mtr-btn button-navy ripple" href= "{% url 'post_detail' slug= post.slug %}">Continue reading →</a><br>
</div>
</article>
{% endif %}
{% endfor %}
The view post_detail(request,slug=None) is to view details about a post. So your URL pattern is incorrect:
path('blog/post-detail/<slug:slug>',views.post_detail,name="post_detail"),
To call it in templates, the simpler and correct way to do is:
<a class="mtr-btn button-navy ripple" href= "{% url 'post_detail' obj.slug %}">Continue reading →</a><br>
</div>
#FOLLOW THIS PROCEDURE.I HOPE IT HELPS YOU OR ANY ONE ELSE IN THE FUTURE
# At blog/urls.py
from django.urls import path
from .views import (post_list, post_detail)
urlspatterns = [
path('blog/', post_list, name='post-list'),
path('<str:slug>/blog/post-detail/', post_detail, name='post-detail'),
]
#At blog/views.py
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_list(request):
posts = Post.objects.all()
template_name = blog/post_list.html
context = {'posts':posts}
return render(request, template_name, context)
def post_detail(request, slug):
posts = get_object_or_404(Post, slug=slug)
template_name = blog/post_detail.html
context = {'posts':posts}
return render(request, template_name, context)
# At the template/blog/post_list.html
{% block content %}
{% for post in posts %}
<article>
<div>
<small>{{ post.created_on|date:"F d, Y" }}</small>
<h2>{{ post.title }}</h2>
<p >{{ post.body }}</p>
</div>
</article>
{% endfor %}
{% endblock content %}
# At template/blog/post_detail.html
<article>
<div>
<small>{{ posts.created_on|date:"F d, Y" }}</small>
<h2>{{ posts.title }}</h2>
<p>{{ posts.body }}</p>
</div>
</article>
#The above code should fix the the issue properly.
If your a following Django 3 By Example Book can check this soltuion because I had the same problem.
Book teach how to create Post with a slug attribute with
models.SlugField and unique_for_date='pusblish' condition.
Then you add some posts from admin site.
Then you add some posts from admin site but then in admin.py book teach how to edit the register with
prepopulated_fields = {'sulg':('title',)}.
Finally, book teach you how to edit posts.
This is a problem because never
going to find a post created. So, the solution for me was delete
posts and the create new ones.
here my code:
models.py
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse
class PublishedManager(models.Manager):
def get_queryset(self):
return super(PublishedManager, self).get_queryset().filter(status='published')
class Post(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published'),
)
title = models.CharField(max_length=250)
slug = models.SlugField(max_length=250, unique_for_date='publish')
author = models.ForeignKey(User,
on_delete=models.CASCADE,
related_name='blog_posts')
body = models.TextField()
publish = models.DateTimeField(default=timezone.now)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
objects = models.Manager() # The default manager.
published = PublishedManager() # Our custom manager.
class Meta:
ordering = ('-publish',)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:post_detail',
args=[self.publish.year,
self.publish.month,
self.publish.day, self.slug])
admin.py
from django.contrib import admin
from .models import Post
#admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'slug', 'author', 'publish', 'status')
list_filter = ('status', 'created', 'publish', 'author')
search_fields = ('title', 'body')
prepopulated_fields = {'slug': ('title',)}
raw_id_fields = ('author',)
date_hierarchy = 'publish'
ordering = ('status', 'publish')
views.py
from django.shortcuts import render, get_object_or_404
# another views...
def post_detail(request, year, month, day, post):
post = get_object_or_404(Post, slug=post,
status='published',
publish__year=year,
publish__month=month,
publish__day=day)
return render(request,
'blog/post/detail.html',
{'post': post})
blog/urls.py
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
# post views
path('', views.PostListView.as_view(), name='post_list'),
path('<int:year>/<int:month>/<int:day>/<slug:post>/',
views.post_detail,
name='post_detail'),
]
my_site/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls', namespace='blog')),
]

Django 1.10 doesn't show post from db

I'm learning django framework writing a blog. I've added some posts in django-admin and I want to show them on web.
MODELS.PY
from django.db import models
from django.utils import timezone
from django.core.urlresolvers import reverse
class PublishedManager(models.Manager):
def get_queryset(self):
return super(PublishedManager,
self).get_queryset()\
.filter(status='published')
class Post(models.Model):
STATUS_CHOICES = (
('draft', 'Roboczy'),
('publish', 'Opublikowany')
)
title = models.CharField(max_length=300)
slug = models.SlugField(max_length=300, unique_for_date='publish')
body = models.TextField()
publish = models.DateTimeField(default=timezone.now)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=20,
choices=STATUS_CHOICES,
default='draft')
object = models.Manager()
published = PublishedManager()
class Meta:
ordering = ('-publish',)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:post_detail',
args=[self.publish.year,
self.publish.strftime('%m'),
self.publish.strftime('%d'),
self.slug])
VIEWS.PY
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_list(request):
posts = Post.published.all()
return render(request,
'blog/post/list.html',
{'posts': posts})
def post_detail(request, year, month, day, post):
post = get_object_or_404(Post, slug=post,
status ='published',
publish_year=year,
publish_month=month,
publish_day=day)
return render(request,
'blog/post/detail.html',
{'post': post})
URLS.PY at BLOG APP
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.post_list, name='post_list'),
url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$'
r'(?P<post>[-\w]+)/$',
views.post_detail,
name='post_detail'),
]
URLS.PY (project level)
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^blog/', include('blog.urls',
namespace='blog',
app_name='blog')),
]
list.html
{% extends "blog/base.html" %}
{% block title %}My Blog {% endblock %}
{% block content %}
<h1>Mój BLOG</h1>
{% for post in posts %}
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p>
Opublikowane {{ post.publish }} przez {{ post.author }}
</p>
{{ post.body|truncatewords:30|linebreaks}}
{% endfor %}
{% endblock %}
I don't know why these posts aren't shown on list.html. I think the mistake is in get_absolute_url.
Instead of posts = Post.published.all()
Try
posts = Post.objects.all()
Ok it's work i must change posts = Post.objects.all() and on list.htlm
<a href="{{ post.get_absolute_url }}">
to
<a href="{{ posts }}">
Urlpatterns are wrong.
url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$'
r'(?P<post>[-\w]+)/$',
views.post_detail,
name='post_detail'),
According to the views the url pattern should be:
url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<post>[-\w]+)/$',
views.post_detail,
name='post_detail'),
Also, Views are wrong:
def post_detail(request, year, month, day, post):
post = get_object_or_404(Post, slug=post,
status ='published',
publish__year=year,
publish__month=month,
publish__day=day)
return render(request,
'blog/post/detail.html',
{'post': post})
Please note that query fields are publish__year (not publish_year), publish___month(not publish_month) and publish__date( not publish_date)
Once you make these changes, the get_absolute_url will also work fine.
I don't know if you want to use Post.objects.all() or Post.published.all(). Ideally, it should be Post.published.all() because in general, only published posts are displayed.

Categories

Resources