Not Found: /post/12/responses/ - django

What I am trying to do is to get particular post comments.
models.py
class Post(models.Model):
title = models.CharField(max_length = 100)
content = models.TextField()
date = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
class Comments(models.Model):
post = models.ForeignKey(Post,related_name='comments',on_delete=models.CASCADE)
name = models.CharField(max_length=50)
date = models.DateTimeField(default=timezone.now)
content = models.TextField()
def get_absolute_url(self):
return reverse('Home')
views.py
class CommentDetailView(DetailView):
model = Comments
template_name = 'CovidHelp/comment_response.html'
context_object_name = 'comments'
paginate_by = 10
def get_queryset(self):
post = get_object_or_404(Post, id=self.kwargs.get('pk'))
return Comments.objects.filter(post=post).order_by('-date')
urls.py
path('post/<int:pk>/responses/', CommentDetailView.as_view(), name='responses')
However I'm getting error when trying to access such an url:
Not Found: /post/12/responses/

you want to return a list of comments for a post right?
so you need to use Listview instead of using detailview to return a list of comments and then use get_queryset to filter it by the post id.

Related

'function' object has no attribute 'order_by'

i am creating a simple blog website in django and have a model which contains time at which the blog will be published when in views i am trying to sort the post according to time it is giving error 'function' object has no attribute 'order_by'
my views.py:
class AboutView(TemplateView):
template_name = 'blog/about.html'
class Postlistview(ListView):
model = Post
def get_queryset(self):
return Post.objects.filter(published_date__lte=timezone.now.order_by('-published_date'))
my models.py :
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=100)
text = models.TextField(max_length=200)
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = models.DateTimeField(default=timezone.now)
self.save()
def get_absolute_url(self):
return reverse('post_detail', kwargs={'pk': self.pk})
def approve_comments(self):
return self.comments.filter(approved_comments=True)
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey('blog.Post', related_name='comments', on_delete=models.CASCADE)
text = models.CharField(max_length=200)
author = models.CharField(max_length=20)
create_date = models.DurationField(default=timezone.now)
approved_comments = models.BooleanField(default=False)
def approve(self):
self.approved_comments = True
self.save()
def get_absolute_url(self):
return reverse('post_list')
def __str__(self):
return self.text
i think it is rather like this:
return Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
the order_by must be outside of your filter.

Get current post's category

So as the title says, i need to get the current post's category to use it in a "related posts" section, more precisely what to put in cat_posts = Post.objects.filter(Category=????)
(don't mind the comments variable since i removed part of my PostView from this post)
here's my code
views.py
def PostView(request, slug):
template_name = 'post-page.html'
post = get_object_or_404(Post, slug=slug)
comments = post.comments.filter(active=True)
cat_posts = Post.objects.filter(Category=Post.Category)
cat_posts = cat_posts.order_by('-Date')[:3}
return render(request, template_name, {'post': post,
'cat_posts':cat_posts})
models.py
class Category(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return str(self.name)
class Post(models.Model):
title = models.CharField(max_length=120)
Category = models.CharField(max_length=120, default='None')
Thumbnail = models.ImageField(null=True, blank=True, upload_to="images/")
Text = RichTextField(blank=False, null=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
Overview = models.CharField(max_length=400)
Date = models.DateTimeField(auto_now_add=True)
main_story = models.BooleanField(default=False)
def __str__(self):
return str(self.title)
def get_absolute_url(self):
# return reverse('about', args=(str(self.id)))
return reverse('home')
You can obtain this with the post.Category (so the post *object, not the Post class):
def PostView(request, slug):
template_name = 'post-page.html'
post = get_object_or_404(Post, slug=slug)
comments = post.comments.filter(active=True)
cat_posts = Post.objects.filter(
Category=post.Category
).order_by('-Date')[:3]
return render(
request,
template_name,
{'post': post, 'cat_posts':cat_posts}
)
It is however better to work with a ForeignKey [Django-doc] to the Category than a CharField: if you later change the name of the category, then your posts are no longer pointing to a valid category.
Note: normally the name of the fields in a Django model are written in snake_case, not PerlCase, so it should be: category instead of Category.

How to delete object using function based view?

I am having trouble trying to implement a delete function-based view as I am unsure of what is the correct syntax.
So far this is the method that I am using:
def delete_lesson(request, post_id):
if request.method == 'POST':
lesson = Lesson.objects.get(post_id=request.get('post_id'))
lesson.delete()
return redirect('/')
I have implemented the delete function in my model:
class Lesson(models.Model):
title = models.CharField(max_length=100)
file = models.FileField(upload_to="lesson/pdf")
date_posted = models.DateTimeField(default=timezone.now)
post = models.ForeignKey(Post, on_delete=models.CASCADE, null=False, blank=False)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('lesson_upload', kwargs={'pk': self.pk})
def delete(self, *args, **kwargs):
self.file.delete()
self.title.delete()
super().delete(*args, **kwargs)
class Post(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(default = 'default0.jpg', upload_to='course_image/')
description = models.TextField()
price = models.DecimalField(decimal_places=2, max_digits=6)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
rating = models.IntegerField(default = 0)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk' : self.pk})
My urls.py:
path('post/<int:post_id>/lesson_delete/', views.delete_lesson, name='delete_lesson'),
You have a post_id in your URL which passes the id to your view which you also received.
So if you want to remove the post with the id in your URL then this is how you can do:
lesson = Lesson.objects.get(post_id=post_id)
If for any reasons you get a post id from your template and it's different than the post id in your URL, then this is how you should do it:
Lesson.objects.get(post_id=request.POST.get('post_id'))
Note if you're using the second option which the post_id you want to delete is different than what you have in post/<int:post_id>/lesson_delete/ then you should pass the post_id as a POST data from your template.

How to save the attribute of my ForeignKey?

I am trying to create a view that allows users to upload their documents in my Lessons model. However when documents are uploaded, I am not able to save the instance in which the form is being submitted. When I access the admin page, the field for my ForeignKey is left empty.
This is the views.py for users to submit their documents:
class UploadLessonView(CreateView):
model = Lesson
fields = ['title', 'file']
template_name = 'store/upload_lesson.html'
success_url = '../'
def form_valid(self, form):
form.instance.author = self.request.user
return super(UploadLessonView, self).form_valid(form)
This is the models.py for my child model:
class Lesson(models.Model):
title = models.CharField(max_length=100)
file = models.FileField(upload_to="lesson/pdf")
date_posted = models.DateTimeField(default=timezone.now)
post = models.ForeignKey(Post, on_delete=models.CASCADE, null=True, blank=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('lesson_upload', kwargs={'pk': self.pk})
For my parent model:
class Post(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(default = 'default0.jpg', upload_to='course_image/')
description = models.TextField()
price = models.DecimalField(decimal_places=2, max_digits=6)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
rating = models.IntegerField(default = 0)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk' : self.pk})
Field for Post is left empty when I submit documents.
You are not setting the Post object in Lesson with the View. So you can fix it in two ways.
One way, is to send it via url, for example:
# url
url('lesson/<int:post_id>/create/', UploadLessionView.as_view())
And use the value of post_id in View:
class UploadLessonView(CreateView):
model = Lesson
fields = ['title', 'file']
template_name = 'store/upload_lesson.html'
success_url = '../'
def form_valid(self, form):
form.instance.post = get_object_or_404(Post, pk=self.kwargs.get('post_id'))
return super(UploadLessonView, self).form_valid(form)
Two, you can add post in fields:
class UploadLessonView(CreateView):
model = Lesson
fields = ['title', 'file', 'post'] # <-- Here
template_name = 'store/upload_lesson.html'

How to call ManyToManyField in class based view

I'm just bricked here; I don’t know what is going on?
I want to do simple blog.
So as you can see below I defined ManyToManyField and set category as a many to many field and then related the name posts.
Earlier I used a function based view and I simply called it a related name like this:
example
def catdetail(request, slug):
code here
and
posts = category.pots.all() /////and this gave me all posts related to this cateogry,
But in the class based view in the category detail view I cannot call this category field from Post; all my tries are unsuccessful; errors like, category has not defined, category has no object, category or post and thing similar to that which you already know…
So my question is: how can I call this related name in Detail view in category?
Here are my models and views.py:
class Category(models.Model):
title = models.CharField(max_length=20)
slug = models.SlugField(unique=True)
def __unicode__(self):
return self.title
def get_absolute_url(self):
return reverse("category_detail", kwargs={"slug": self.slug})
class Tag(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(unique=True)
def __unicode__(self):
return self.title
class Post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
category = models.ManyToManyField(Category, related_name='posts')
title = models.CharField(max_length=100, blank=False)
slug = models.SlugField(unique=True)
body = models.TextField()
image = models.ImageField(upload_to='project/uploads/')
tag = models.ManyToManyField(Tag, related_name='tag_post')
date = models.DateTimeField(auto_now_add=True, auto_now=False)
date_mod = models.DateTimeField(auto_now=True, auto_now_add=False)
publis = models.BooleanField(default=True)
def __unicode__(self):
return self.title
def get_absolute_url(self):
return reverse("post_detail", kwargs={"slug": self.slug})
and views.py.
Can you tell me how to call the category field and related name here in views?
class CategoryDetail(DetailView):
model = Category
template_name = "cat_detail.html"
def get_context_data(self, *args, **kwargs):
context = super(CategoryDetail, self).get_context_data(*args, **kwargs)
context['cat'] = get_object_or_404(Category, slug=self.kwargs.get("slug"))
return context
Some help?
def get_context_data(self, *args, **kwargs):
context = super(CategoryDetail, self).get_context_data(*args, **kwargs)
posts = Category.objects.get(id=1).posts.all()
for post in posts:
post.category
print post
context['cat'] = get_object_or_404(Category, slug=self.kwargs.get("slug"))
return context
i now have this, but i got all posts whether be on that category or not