How to delete object using function based view? - django

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.

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.

Not Found: /post/12/responses/

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.

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 get pk value of another model in current model's get absolute url django

I am learning django. I am very new to programming. I have one model as below:
class Group(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
group_description = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
def get_absolute_url(self):
self.save()
return reverse('group-detail', kwargs={'pk': self.pk})
now I am creating another model which needs the pk value of the above Group model:
class GroupPost(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)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('group-post-detail', kwargs={'pk': Group.pk, 'pk2': self.pk})
when I give just Group.pk it is erroring out giving the below information.
Reverse for 'group-post-detail' with keyword arguments '{'pk': , 'pk2': 73}' not found. 1 pattern(s) tried: ['groups/(?P[0-9]+)/post/(?P[0-9]+)/$']
How can I get rid of the error message. what is the correct way to proceed? Any help would be appreciated.
Thank you
You should have a many-to-one relationship (ForeignKey) with the Group model from the GroupPost model, as each post belongs to a certain group and one group can have many posts.
So add a ForeignKey:
class GroupPost(models.Model):
...
group = models.ForeignKey('Group', on_delete=models.CASCADE)
Now, you can refer the related Group id (or pk) from a GroupPost instance:
def get_absolute_url(self):
return reverse('group-post-detail', kwargs={'pk': self.group.pk, 'pk2': self.pk})
# ^^^^^^ Here
Assuming the view name is group-post-detail.
Also, rather than referring URL keywords as pk and pk2, you can be more explicit:
def get_absolute_url(self):
return reverse('group-post-detail', kwargs={'group_pk': self.group.pk, 'group_post_pk': self.pk})

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