How to make the post title available at my template - python

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 }}

Related

Django : Why is my submit interest form not submitted. Did I write my view or template wrongly?

Django : Why is my submit interest form not submitted. Did I write my view or template wrongly?
Based on the view I wrote, I dont even get redirected after I click on submit. And when i return to the home page, i Receive a message from here
messages.warning(request, 'Something went wrong. Please try again..', extra_tags='wronginterest')
which is why I believe it is because the form is not valid thats why it is not submitting. but wth why is it not valid?? Thanks
views.py
def submit_interest_view(request, slug):
user = request.user
blog_post = BlogPost.objects.get(slug=slug)
num_blogpost = BlogPost.objects.filter(author=request.user).count()
if not user.is_authenticated:
return redirect('must_authenticate')
elif blog_post.author == request.user:
return HttpResponse('You cannot submit interest to your own post.')
interest_requests = Interest.objects.filter(interestsender=request.user, interestreceiver=blog_post.author)
for interest_request in interest_requests:
if interest_request.is_active:
return HttpResponse('You have already submitted your interest to this post.')
if request.method == 'POST': # use request.method == 'POST' to submit POST request (like submitting a form)
form = SubmitInterestForm(request.POST, request.FILES)
if form.is_valid():
obj = form.save(commit=False)
author = Account.objects.get(email=user.email) # use get if you aim to get a single object not a queryset
obj.author = author
obj.blog_post = blog_post
obj.save()
messages.success(request, 'Your interests have been submitted', extra_tags='submittedinterest')
context['success_message'] = "Updated"
if request.META.get('HTTP_REFERER') == request.build_absolute_uri(reverse("HomeFeed:main")):
return redirect(reverse("HomeFeed:main"))
elif request.META.get('HTTP_REFERER') == request.build_absolute_uri(reverse("HomeFeed:detail", kwargs={'slug': slug })):
return redirect(reverse('HomeFeed:detail', kwargs={'slug': slug}))
else:
return redirect(reverse('HomeFeed:main'))
#return redirect(reverse('HomeFeed:detail', kwargs={'slug': slug})) # redirect to your post detail but use reverse to pass kwargs not just redirect
else:
messages.warning(request, 'Something went wrong. Please try again..', extra_tags='wronginterest')
else:
form = SubmitInterestForm() # if request.method isnt POST you still need to define your form so it can be displayed
return render(request, "HomeFeed/submitinterest.html", {'form': form,'user': user, 'num_blogpost': num_blogpost, 'blog_post': blog_post}) # context dict
forms.py
HomeFeed: forms.py:
class SubmitInterestForm(forms.ModelForm):
class Meta:
model= Interest
fields = ['my_name', 'my_thoughts','short_file',]
models.py
class Interest(models.Model):
interestsender = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='interestsender', on_delete=models.CASCADE)
interestreceiver = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='interestreceiver', on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(blank=False, null=False, default=True)
my_name = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
blog_post = models.ForeignKey(BlogPost, on_delete=models.CASCADE)
my_thoughts = models.TextField(max_length=5000, null=False, blank=False)
short_file = models.FileField(upload_to='documents/', null=True, blank=True)
def upload_location(instance, filename):
#you define this variable called file_path. It belongs to the HomeFeed app, and takes in the parameter of author id, title of blog post with the file name that the author uploads it, and you want to format it
file_path = 'HomeFeed/{author_id}/{title}-{filename}'.format(
author_id=str(instance.author.id),title=str(instance.chief_title), filename=filename)
#the above will let you insert the strings, you want to take ID of the user who is uploading and converting it into a string, and also the title and file name, converting them into string
# return file path means where the images is stored, either the local machine/ production environment which will be the name file stored in the content delivery network
return file_path
class BlogPost(models.Model):
chief_title = models.CharField(max_length=50, null=False, blank=False)
body = models.TextField(max_length=5000, null=False, blank=False)
likes = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='blog_posts', blank=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
slug = models.SlugField(blank=True, unique=True)
date_published = models.DateTimeField(auto_now_add=True, verbose_name="date published")
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
html:
submit_interest.thml
<form method="post" enctype="multipart/form-data">{% csrf_token %}
<div class="form-group">
<input class="form-control bg-white form-control-plaintext c" rows="10" type="text" name="my_name" id="my_name" placeholder="Name: {{ request.user.username }}" readonly></input>
</div>
<div class="form-group">
<label for="my_thoughts text-dark">thoughts:</label>
<textarea class="form-control" rows="6" type="text" name="my_thoughts" id="my_thoughts" placeholder="My thoughts..." required></textarea >
</div>
<label for="short_file " class="text-dark">Brief file (Optional):</label>
<input type="file" class="btn btn-md btn-light" name="short_file" id="short_file"> <!--<button type="submit" class="btn btn-md btn-info">Upload</button>-->
{% if uploaded_file_url %}
<p>File uploaded at: {{ uploaded_file_url }}</p>
{% endif %}
<button class="submit-button btn btn-lg btn-primary mt-3 btn-block col-lg-6 offset-lg-3 " type="submit">Submit Interest</button>
</form>
urls.py
app_name = 'HomeFeed'
urlpatterns = [
path('', home_feed_view , name= "main"),
path('submitinterest/<slug>', submit_interest_view, name= "submitinterest"),
You need to find out why this is not validating. When the form is not valid, send the form instance back to template via context and try to render the errors. For example:
# view
if form.is_valid():
# ...
else:
messages.warning(request, 'Something went wrong. Please try again..', extra_tags='wronginterest')
return render(request, "HomeFeed/submitinterest.html", {'form': form,'user': user, 'num_blogpost': num_blogpost, 'blog_post': blog_post}) # context dict
# template
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
For more details on form error rendering, please see the documentation.
BTW some minor optimisation on your code:
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404
#login_required
def submit_interest_view(request, slug):
user = request.user
blog_post = get_object_or_404(BlogPost, slug=slug)
num_blogpost = BlogPost.objects.filter(author=user).count()
if blog_post.author.email == user.email:
return HttpResponse('You cannot submit interest to your own post.')
interest_requests = Interest.objects.filter(interestsender=user, interestreceiver=blog_post.author, is_active=True)
if interest_requests.exists():
return HttpResponse('You have already submitted your interest to this post.')
if request.method == 'POST': # use request.method == 'POST' to submit POST request (like submitting a form)
form = SubmitInterestForm(request.POST, request.FILES)
if form.is_valid():
obj = form.save(commit=False)
author = Account.objects.get(email=user.email) # use 'author = user.account' if there is OneToOne relation between user and account
obj.author = author
obj.blog_post = blog_post
obj.save()
messages.success(request, 'Your interests have been submitted', extra_tags='submittedinterest')
context['success_message'] = "Updated"
if request.META.get('HTTP_REFERER') == request.build_absolute_uri(reverse("HomeFeed:main")):
return redirect(reverse("HomeFeed:main"))
elif request.META.get('HTTP_REFERER') == request.build_absolute_uri(reverse("HomeFeed:detail", kwargs={'slug': slug })):
return redirect(reverse('HomeFeed:detail', kwargs={'slug': slug}))
else:
return redirect(reverse('HomeFeed:main'))
#return redirect(reverse('HomeFeed:detail', kwargs={'slug': slug})) # redirect to your post detail but use reverse to pass kwargs not just redirect
else:
messages.warning(request, 'Something went wrong. Please try again..', extra_tags='wronginterest')
return render(request, "HomeFeed/submitinterest.html", {'form': form,'user': user, 'num_blogpost': num_blogpost, 'blog_post': blog_post})
else:
form = SubmitInterestForm() # if request.method isnt POST you still need to define your form so it can be displayed
return render(request, "HomeFeed/submitinterest.html", {'form': form,'user': user, 'num_blogpost': num_blogpost, 'blog_post': blog_post}) # context dict

Getting all the users name who liked a post in django

I am trying to show the List of Users who Liked a Particular Post. Here is what I have tried but nothing is showing.
I have created the post_likes in the views.py and tried to loop through its users in the post-details.html:
Here is the post_detail.html template:
{% for user in post_likes %}
<p>{{ user.username }}f</p>
{% endfor %}
but nothing is showing.
Here is the Post Models.py:
class Post(models.Model):
content = RichTextUploadingField(null=True, blank=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='author')
likes = models.ManyToManyField(User, related_name='liked', blank=True)
Here are the like model.py:
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
value = models.CharField(choices=LIKE_CHOICES, default='Like', max_length=8)
Here are the views.py:
class PostDetailView(DetailView):
model = Post
template_name = "blog/post_detail.html" # <app>/<model>_<viewtype>.html
def get_context_data(self, *args, **kwargs):
context = super(PostDetailView, self).get_context_data()
post = get_object_or_404(Post, slug=self.kwargs['slug'])
comments = Comment.objects.filter(
post=post).order_by('-id')
total_likes = post.total_likes()
liked = False
if post.likes.filter(id=self.request.user.id).exists():
liked = True
if self.request.method == 'POST':
comment_form = CommentForm(self.request.POST or None)
--------Comment Related Lines--------------------------------
else:
comment_form = CommentForm()
context["comments"] = comments
context["comment_form"] = comment_form
context["total_likes"] = total_likes
context["liked"] = liked
return context
def get(self, request, *args, **kwargs):
res = super().get(request, *args, **kwargs)
self.object.incrementViewCount()
if self.request.is_ajax():
context = self.get_context_data(self, *args, **kwargs)
html = render_to_string('blog/comments.html', context, request=self.request)
return JsonResponse({'form': html})
return res
def LikeView(request):
post = get_object_or_404(Post, id=request.POST.get('id'))
liked = False
current_likes = post.num_likes
user = request.user
if post.author.id == request.user.id:
messages.warning(request, 'You can not like you own Post')
else:
if post.likes.filter(id=request.user.id).exists():
post.likes.remove(request.user)
liked = False
current_likes = current_likes - 1
else:
post.likes.add(request.user)
liked = True
current_likes = current_likes + 1
post.num_likes = current_likes
post.save()
like, created = Like.objects.get_or_create(user=user, post=post)
if not created:
if like.value == 'Like':
like.value = 'Unlike'
else:
like.value = 'Like'
like.save()
context = {
'total_likes': post.total_likes,
'liked': liked,
'post': post
}
if request.is_ajax:
html = render_to_string('blog/like_section.html', context, request=request)
return JsonResponse({'form': html})
def post_likes(request, self):
posts = get_object_or_404(Post, slug=self.kwargs['slug'])
post_likes = posts.likes.all()
context = {'post_likes': post_likes, }
return render(request, 'blog/post_detail.html', context)
my question is:
How can I see the usernames who liked the particular post?
In your template, replace
{% for user in post_likes %}
<p>{{ user.username }}f</p>
{% endfor %}
with
{ % for like in post_likes %}
<p> {{ like.user.username }} </p>
{ % endfor %}

Django form does not save new post using based view function

I have a model as follow:
class Post(models.Model):
title = models.CharField(max_length=150)
author = models.ForeignKey(User, on_delete=models.CASCADE)
date_posted = models.DateTimeField(default=timezone.now)
imagefile = models.FileField(null=True, blank=True, upload_to='images', default='default.jpg')
There is a bug in the view file that, when I use class base view I can post the new post but whenever I use it as a function it does not save the form.
This one works(saves post in database):
class PostCreateView(LoginRequiredMixin, AjaxFormMixin, CreateView):
model = Post
template_name = "app/postform.html"
success_url = '/posts'
form_class = postform
But this one does not(does not save post in database):
#login_required
def PostCreateView(request):
if request.method == 'POST':
mform = postform(request.POST or None, request.FILES or None, instance=request.user)
if mform.is_valid():
mform.save() # when I print something here, Ill see something
messages.success(request, f'Yes!')
return redirect('posts')
else:
mform = postform()
return render(request, 'myapplication/postform.html', {'form': mform})
and in postform.html:
<form method="POST" action="" enctype="multipart/form-data">
<fieldset class="form-group">
{% csrf_token %}
<div class="content-section">
<!-- {{ form|crispy }} -->
</div>
</fieldset>
</form>
and form.py:
class postform(forms.ModelForm):
class Meta:
model = Post
fields = ("__all__")
exclude = ['date_posted']
I think the problem is that you form's model is post and you're assigning object of user as instance.
So try this way:
#login_required
def PostCreateView(request):
if request.method == 'POST':
mform = postform(request.POST or None, request.FILES or None)
if mform.is_valid():
post = mform.save(commit=False)
post.author = request.user
post.save()
messages.success(request, f'Yes!')
return redirect('posts')
else:
mform = postform()
return render(request, 'myapplication/postform.html', {'form': mform})

How to display post name on new_comment page

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})

How to add a comment to post? PostDetailVew, Django 2.1.5

I want add comment to post on his page ("post detail" page).
I was find answer, but it create comment on other page. I want create comment on page of "post detail".
urls.py
url(r'^post/(?P<pk>\d+)/create/$', views.CommentCreate.as_view(), name='comment_create'),
models.py
class Comment(models.Model):
description = RichTextUploadingField()
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
comment_date = models.DateTimeField(auto_now_add=True, null=True)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
class Meta:
ordering = ["-comment_date"]
def __str__(self):
return "{}".format(self.description)
forms.py
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['description']
views.py
class PostDetailView(generic.DetailView):
model = Post
class CommentCreate(LoginRequiredMixin, CreateView):
model = Comment
fields = ['description']
def get_context_data(self, **kwargs):
context = super(CommentCreate, self).get_context_data(**kwargs)
context['post'] = get_object_or_404(Post, pk = self.kwargs['pk'])
return context
def form_valid(self, form):
form.instance.author = self.request.user
form.instance.post=get_object_or_404(Post, pk = self.kwargs['pk'])
return super(CommentCreate, self).form_valid(form)
def get_success_url(self):
return reverse('post-detail', kwargs={'pk': self.kwargs['pk'],})
comment_form.html
...
<form action="" method="post">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<button type="submit">Submit</button>
</form>
...
post_detail.html
...
{% for comment in post.comment_set.all %}
<p>{{ comment.author }} ({{ comment.comment_date }}) {{ comment.description|safe }}</p>
{% endfor %}
<hr>
{% if user.is_authenticated %}
<p>Add a new comment</p>
...
I think, "comment_form" need to redirect to "post_detail", not generate new page for comment form.
And сould you tell, which parameters has a RichTextField (CKE), how change width, height field only in comment?
If you want the comment form right in your detail page then all you have to do is to add the form and post function in your View,
class PostDetailView(DetailView):
model = Post
template_name = 'yourdetailpage.html'
def get_context_data(self, **kwargs):
context = super(PostDetailView, self).get_context_data(**kwargs)
context['commentform'] = CommentForm()
return context
def post(self, request, pk):
post = get_object_or_404(Post, pk=pk)
form = CommentForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
obj.post = post
obj.author = self.request.user
obj.save()
return redirect('detail', post.pk)
And now you can add your form in your html. And add a submit button to post comment.

Categories