How to display post name on new_comment page - python

i would like to know how i can display the name of a post at my comment_new page:
views.py
def comment_new(request, pk):
if request.method == "POST":
form = CommentForm(request.POST)
post = get_object_or_404(Post, pk=pk)
if form.is_valid():
comment = form.save(commit=False)
comment.author = request.user
comment.published_date = timezone.now()
comment.post = post
comment.save()
messages.success(request, 'You have successfully provided a comment for this Post.')
return redirect('post_detail', pk=comment.post.pk)
else:
form = CommentForm(request.POST)
return render(request, 'app/comment_new.html', {'form': form})
else:
form = CommentForm()
return render(request, 'app/comment_new.html', {'form': form})
models.py
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(verbose_name="Post Title", max_length=40)
content = models.TextField(verbose_name="Post Content", max_length=5000)
tag = models.CharField(verbose_name="Tags/Meta - (sep. by comma)", max_length=50, blank=True)
category = models.ForeignKey(Category, verbose_name="Category", on_delete=models.CASCADE, null=True)
template.html
<a>{{ post.title }}</a>
the attribute title is given. I have no idea why it does not work.
thanks in Advance

I'll assume you want to display the post title when a user is about to add a new comment. I mean, when the request is a GET (display the new message form).
def comment_new(request, pk):
# This line is better here since you'll be working with
# the post instance no matter the request method is POST or GET.
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
# ...
else:
form = CommentForm()
# And here pass post as part of the context to your template.
return render(request, 'app/comment_new.html', {'form': form, 'post': post})

Related

Why Django Is Not Accepting Data From A Form Even Data Is Valid? Django-python

I am Working With Modals And Forms In Django I Created A Comment Modal For My Post Modal I Used A ForeignKey To Associate My Comments With Posts, It Works All Fine By Manually Adding Comments To Posts From Admin Sections Of My Webpage, But As Soon As I Try To Do The Same Thing Using A Front-End Represtantion Of My Form So That User Could Add Comments To Posts, It Doesn't Work As Expected And I Am Also Unable To Automatically Associate My Posts With My Comments, I Have Been Changing The Things Form 2 Days Now And Still The Result Is Still Same. Can Anyone Help Me :{
This Is How My Modal Look Like:
class Comment(models.Model):
post = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='comments')
author = models.CharField(max_length=200)
text = RichTextField()
created_date = models.DateTimeField(auto_now_add= True)
active = models.BooleanField(default=False)
The Form:
class CommentForm(forms.ModelForm):
class Meta:
model = models.Comment
fields = ['author', 'text']
And This My View in Views.py:
def article_detail(request, slug):
article = Article.objects.get(slug = slug)
articles = Article.objects.all()
comment_form = CommentForm()
post = get_object_or_404(Article, slug=slug)
comments = post.comments.filter(active=True)
if request.method == 'POST':
form = forms.CreateArticle(request.POST, request.FILES)
if form.is_valid():
# Create Comment object but don't save to database syet
new_comment = form.save()
# Assign the current post to the comment
new_comment.post = comment_form.instance.article_id
# Save the comment to the database
new_comment.save()
else:
comment_form = CommentForm()
return render(request, 'articles/article_detail.html', {'article':article, 'articles':articles, 'comment_form': comment_form , })
And The Form Front-End Representation Is As:
<form method="post" style="margin-top: 1.3em;">
{{ comment_form }}
{% csrf_token %}
<button type="submit" class="btn btn-outline-success">Submit</button>
</form>
Your correct code should be looked like this
def article_detail(request, slug):
articles = Article.objects.all()
comment_form = CommentForm()
post = get_object_or_404(Article, slug=slug)
comments = post.comments.filter(active=True)
if request.method == 'POST':
form = CommentForm(data=request.POST, files=request.FILES)
if form.is_valid():
# Create Comment object but don't save to database syet
new_comment = form.save(commit=False)
new_comment.post = post
new_comment.save()
else:
comment_form = CommentForm()
return render(request, 'articles/article_detail.html', {'article':post, 'articles':articles, 'comment_form': comment_form })

Insert comment form on Post detail page. django- blog app

I have trying this from 2-3 days. I want to insert my comment form on post detail page.
My form is not showing on that page.
I have followed this tutorial for the comment model.
I have another app for account which is used for signup purpose.
model.py
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def __str__(self):
return self.title
def publish(self):
self.published_date = timezone.now()
self.save()
def approved_comments(self):
return self.comments.filter(approved_comment=True)
class Comment(models.Model):
post = models.ForeignKey('Post', on_delete=models.CASCADE, related_name='comments')
author = models.CharField(verbose_name ='Username',max_length=200)
text = models.TextField(verbose_name ='Comment')
email = models.EmailField(default='')
created_date = models.DateTimeField(default=timezone.now)
approved_comment = models.BooleanField(default=False)
def approve(self):
self.approved_comment = True
self.save()
def __str__(self):
return self.text
view.py
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})
def add_comment_to_post(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.save()
return redirect('post_detail', pk=post.pk)
else:
form = CommentForm()
return render(request, 'blog/add_comment_to_post.html', {'form': form})
#login_required
def comment_approve(request, pk):
comment = get_object_or_404(Comment, pk=pk)
comment.approve()
return redirect('post_detail', pk=comment.post.pk)
#login_required
def comment_remove(request, pk):
comment = get_object_or_404(Comment, pk=pk)
comment.delete()
return redirect('post_detail', pk=comment.post.pk)
urls.py
path('post/<int:pk>/comment/', views.add_comment_to_post, name='add_comment_to_post'),
path('comment/<int:pk>/approve/', views.comment_approve, name='comment_approve'),
path('comment/<int:pk>/remove/', views.comment_remove, name='comment_remove'),
path('post/<int:pk>/', views.post_detail, name='post_detail'),
Please help me out to find a way to insert it in my post_deatil.html.
In case you want the same page to see the post and also add a comment you only need one view like:
def post_details(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.save()
return redirect('post_detail', pk=post.pk)
else:
form = CommentForm()
return render(request, 'blog/post_details.html', {'form': form, 'post': post})
Then your url will be like:
path('post/<int:pk>/', views.post_details, name='post-details'),
And finally you have to mix both of your templates, first showing the information of the post and on the bottom adding the form.
With that you will be able to delete the add_comment_to_post view and url.

Implementing pageviews in Django

I am working on a small a small website and I want to display the total views of every object in the detail view. But sincerely, I don't know how to actualise this. Let me post my models.py and views.py
Models.py
class Music(models.Model):
artist = models.CharField(max_length=300)
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(default='', blank=True, unique=True)
thumbnail = models.ImageField(blank=False)
audio_file = models.FileField(default='')
uploaded_date = models.DateTimeField(default=timezone.now)
class Meta:
ordering = ['-uploaded_date']
def save(self):
self.uploaded_date = timezone.now()
self.slug = slugify(self.title)
super(Music, self).save()
def __str__(self):
return self.title + ' by ' + self.artist
def get_absolute_url(self):
return reverse('music:detail', kwargs={'slug': self.slug})
Views.py
return Music.objects.order_by('-uploaded_date')
def detail(request, slug):
latest_posts = Music.objects.order_by('-uploaded_date')[:5]
song = get_object_or_404(Music, slug=slug)
comments = Comment.objects.filter(post=song)
if request.method == 'POST':
comment_form = CommentForm(request.POST or None)
if comment_form.is_valid():
comment = comment_form.save(commit=False)
comment.post = song
comment.save()
return HttpResponseRedirect(song.get_absolute_url())
else:
comment_form = CommentForm()
context = {
'latest_posts': latest_posts,
'song': song,
'comments': comments,
'comment_form': comment_form,
}
return render(request, 'music/detail.html', context)
You can add an IntegerField to your Music model called page_views:
class Music(models.Model):
...
page_views = IntegerField(default=0)
Then borrowing from this answer you can increment views for the individual song from your detail view whenever the page is requested:
def detail(request, slug):
latest_posts = Music.objects.order_by('-uploaded_date')[:5]
song = get_object_or_404(Music, slug=slug)
comments = Comment.objects.filter(post=song)
if request.method == 'POST':
comment_form = CommentForm(request.POST or None)
if comment_form.is_valid():
comment = comment_form.save(commit=False)
comment.post = song
comment.save()
return HttpResponseRedirect(song.get_absolute_url())
else:
comment_form = CommentForm()
song.update(page_views=F('page_views') + 1) # Add this line here so it's not updated on POST
context = {
'latest_posts': latest_posts,
'song': song,
'comments': comments,
'comment_form': comment_form,
}
return render(request, 'music/detail.html', context)
Note that you may not want to count someone adding a comment through the form as another view for the page, so it's up to you how you define when the count actually gets incremented. This is just a really basic way to count how many times the page is requested.

Django - redirect after pressing comment delete

I have a code that deletes comments to from posts.
def comment_remove(request, pk):
comment = get_object_or_404(Comment, pk=pk)
comment.delete()
return redirect('Post-detail', pk=post.pk)
It deletes comments, but it throws error that name 'post' is not defined
I have a same function above in my views.py with the same post.pk that works fine...
#login_required
def add_comment_to_post(request, pk):
post = get_object_or_404(Post, pk=pk)
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.author.photo = object.author.profile.image.url
comment.save()
return redirect('Post-detail', pk=post.pk)
else:
form = CommentForm()
return render(request, 'blog/add_comment_to_post.html', {'form': form})
Comment model
class Comment(models.Model):
post = models.ForeignKey('blog.Post', on_delete=models.CASCADE, related_name='comments')
author = models.CharField(max_length=20)
text = models.TextField(max_length=200)
created_date = models.DateTimeField(default=timezone.now)
approved_comment = models.BooleanField(default=False)
def approve(self):
self.approved_comment = True
self.save()
def __str__(self):
return self.text
Can someone please explain me, where is the problem?
Is it taking no post.pk but comment.pk?
You can pick pk from comment object like this
comment = get_object_or_404(Comment, pk=pk)
....
return redirect('Post-detail', pk=comment.post_id)

How to make the post title available at my template

i need to know how i can make the actual postname a comment belongs to available at my template to display it later on:
views.py
def comment_edit(request, pk):
comment = get_object_or_404(Comment, pk=pk)
if request.user == comment.author:
if request.method == "POST":
form = CommentForm(request.POST, instance=comment)
if form.is_valid():
comment = form.save(commit=False)
comment.author = request.user
comment.published_date = timezone.now()
comment.save()
return redirect('post_detail', pk=comment.post.pk)
else:
form = CommentForm(instance=comment)
return render(request, 'app/Post/post_comment_edit.html', {'form': form})
else:
return redirect('post_detail', pk=comment.post.pk)
template.html:
{{ post.category.title }}
{{ post.title }}
models.py
class Comment(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
content = models.TextField(max_length=500)
published_date = models.DateField(auto_now_add=True, null=True)
thanks in advance
pass the comment instance to your template
return render(request, 'app/Post/post_comment_edit.html', {'form': form, 'comment': comment})
and in template
{{ comment.post.category.title }}
{{ comment.post.title }}

Categories