News Feed hidden from users who aren't administrators - python
On my social media platform, the news feed (called post_list) seems to be hidden from any user that isn't an admin.
Even when text is entered into the box and 'post' is pressed, the page refreshes but the text box isn't emptied and no posts appear belowhand.
If I log in as an admin, the feed appears immediately and so do all the posts that I just posted from the non-admin account that didn't appear on the non-admin account. As shown here.
I have just recently added the ability to share posts, so maybe that has influenced this issue in some manner.
(The news feed) post_list.html:
> {% extends 'landing/base.html' %} {% load crispy_forms_tags %}
>
> {% block content %} <div class="container">
> <div class="row justify-content-center mt-3">
> <div class="col-md-5 col-sm-12 border-bottom">
> <h5>Create a Post</h5>
> </div>
> </div>
>
> <div class="row justify-content-center mt-3">
> <div class="col-md-5 col-sm-12 border-bottom">
> <form method="POST" enctype="multipart/form-data">
> {% csrf_token %}
> {{ form | crispy }}
> <div class="d-grid gap-2">
> <button class="btn btn-light" style="background-color: #CC64C3; mt-3 mb-5">Post</button>
> </div>
> </form>
> </div>
> </div>
>
> {% for post in post_list %}
> <div class="row justify-content-center mt-3">
> <div class="col-md-5 col-sm-12 border-bottom position-relative">
> <div>
> <a href="{% url 'profile' post.author.profile.pk %}">
> <img class="rounded-circle post-img" height="30" width="30" src="{{ post.author.profile.picture.url }}" />
> </a>
> <p class="post-text">
> <a class="text-primary post-link" href="{% url 'profile' post.author.profile.pk %}">#{{ post.author }}</a> {{
> post.created_on }}
> </p>
> </div>
> <div class="position-relative">
> <p>{{ post.body }}</p>
>
> {% if post.image.count > 0 %}
> <div class="row">
> {% for img in post.image.all %}
> <div class="col-md-4 col-xs-12">
> <img src="{{ img.image.url }}" class="post-image" />
> </div>
> {% endfor %}
> </div>
> {% endif %}
> <form method="POST" action="{% url 'share-post' post.pk %}" class="d-none" id="{{ post.pk }}">
> {% csrf_token %}
> {{ shareform | crispy }}
> <div class="d-grid gap-2">
> <button class="btn btn-light" style="background-color: #CC64C3; mt-3 mb-5">Share</button>
> </div>
> </form>
> </div>
>
> <div class="d-flex flex-row">
> <form method="POST" action="{% url 'like' post.pk %}">
> {% csrf_token %}
> <input type="hidden" name="next" value="{{ request.path }}">
> <button class="remove-default-btn" type="submit">
> <i class="far fa-thumbs-up"><span>{{ post.likes.all.count }}</span></i>
> </button>
> </form>
>
> <form method="POST" action="{% url 'dislike' post.pk %}">
> {% csrf_token %}
> <input type="hidden" name="next" value="{{ request.path }}">
> <button class="remove-default-btn" type="submit">
> <i class="far fa-thumbs-down"><span>{{ post.dislikes.all.count }}</span></i>
> </button>
> </form>
> <span onclick="shareToggle('{{ post.pk }}')"><i class="far fa-share-square share-btn"></i></span>
> </div>
> </div>
> {% endfor %} </div> {% endblock content %}
views.py:
from django.shortcuts import render, redirect
from django.db.models import Q
from django.utils import timezone
from django.urls import reverse_lazy
from django.shortcuts import redirect
from django.contrib import messages
from django.contrib.auth.models import User
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth.mixins import UserPassesTestMixin, LoginRequiredMixin
from django.views import View
from django.views.generic.edit import UpdateView, DeleteView
from .models import MessageModel, Post, Comment, UserProfile, Notification, ThreadModel, MessageModel, Image
from .forms import PostForm, CommentForm,ThreadForm, MessageForm, ShareForm
class PostListView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
logged_in_user = request.user
posts = Post.objects.filter(
author__profile__followers__in=[logged_in_user.id]
).order_by('-created_on')
form = PostForm()
share_form = ShareForm()
context = {
'post_list': posts,
'shareform': share_form,
'form': form,
}
return render(request, 'social/post_list.html', context)
def post(self, request, *args, **kwargs):
logged_in_user = request.user
posts = Post.objects.filter(
author__profile__followers__in=[logged_in_user.id]
).order_by('-created_on')
form = PostForm(request.POST, request.FILES)
files = request.FILES.getlist('image')
share_form = ShareForm()
if form.is_valid():
new_post = form.save(commit=False)
new_post.author = request.user
new_post.save()
for f in files:
img = Image(image=f)
img.save()
new_post.image.add(img)
new_post.save()
context = {
'post_list': posts,
'share_form': share_form,
'form': form,
}
return render(request, 'social/post_list.html', context)
class PostDetailView(LoginRequiredMixin, View):
def get(self, request, pk, *args, **kwargs):
post = Post.objects.get(pk=pk)
form = CommentForm()
comments = Comment.objects.filter(post=post).order_by('-created_on')
context = {
'post': post,
'form': form,
'comments': comments,
}
return render(request, 'social/post_detail.html', context)
def post(self, request, pk, *args, **kwargs):
post = Post.objects.get(pk=pk)
form = CommentForm(request.POST)
if form.is_valid():
new_comment = form.save(commit=False)
new_comment.author = request.user
new_comment.post = post
new_comment.save()
comments = Comment.objects.filter(post=post).order_by('-created_on')
notification = Notification.objects.create(notification_type=2, from_user=request.user, to_user=post.author, post=post)
context = {
'post': post,
'form': form,
'comments': comments,
}
return render(request, 'social/post_detail.html', context)
class CommentReplyView(LoginRequiredMixin, View):
def post(self, request, post_pk, pk, *args, **kwargs):
post = Post.objects.get(pk=post_pk)
parent_comment = Comment.objects.get(pk=pk)
form = CommentForm(request.POST)
if form.is_valid():
new_comment = form.save(commit=False)
new_comment.author = request.user
new_comment.post = post
new_comment.parent = parent_comment
new_comment.save()
notification = Notification.objects.create(notification_type=2, from_user=request.user, to_user=parent_comment.author, comment=new_comment)
return redirect('post-detail', pk=post_pk)
class PostEditView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Post
fields =['body']
template_name = 'social/post_edit.html'
def get_success_url(self):
pk = self.kwargs['pk']
return reverse_lazy('post-detail', kwargs={'pk': pk})
def test_func(self):
post = self.get_object()
return self.request.user == post.author
class PostDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Post
template_name = 'social/post_delete.html'
success_url = reverse_lazy('post-list')
def test_func(self):
post = self.get_object()
return self.request.user == post.author
class CommentDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Comment
template_name = 'social/comment_delete.html'
def get_success_url(self):
pk = self.kwargs['post_pk']
return reverse_lazy('post-detail', kwargs={'pk': pk})
def test_func(self):
post = self.get_object()
return self.request.user == post.author
class ProfileView(View):
def get(self, request, pk, *args, **kwargs):
profile = UserProfile.objects.get(pk=pk)
user = profile.user
post = Post.objects.filter(author=user).order_by('-created_on')
followers = profile.followers.all()
if len(followers) == 0:
is_following = False
for follower in followers:
if follower == request.user:
is_following = True
break
else:
is_following = False
number_of_followers = len(followers)
context = {
'user': user,
'profile': profile,
'posts': post,
'number_of_followers': number_of_followers,
'is_following': is_following,
}
return render(request, 'social/profile.html', context)
class ProfileEditView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = UserProfile
fields = ['name', 'bio', 'birth_date','location','picture']
template_name = 'social/profile_edit.html'
def get_success_url(self):
pk = self.kwargs['pk']
return reverse_lazy('profile', kwargs={'pk':pk})
def test_func(self):
profile = self.get_object()
return self.request.user == profile.user
class AddFollower(LoginRequiredMixin, View):
def post(self, request, pk, *args, **kwargs):
profile = UserProfile.objects.get(pk=pk)
profile.followers.add(request.user)
notification = Notification.objects.create(notification_type=3, from_user=request.user, to_user=profile.user)
return redirect('profile', pk=profile.pk)
class RemoveFollower(LoginRequiredMixin, View):
def post(self, request, pk, *args, **kwargs):
profile = UserProfile.objects.get(pk=pk)
profile.followers.remove(request.user)
return redirect('profile', pk=profile.pk)
class AddLike(LoginRequiredMixin, View):
def post(self, request, pk, *args, **kwargs):
post = Post.objects.get(pk=pk)
is_dislike = False
for dislike in post.dislikes.all():
if dislike == request.user:
is_dislike = True
break
if is_dislike:
post.dislikes.remove(request.user)
is_like = False
for like in post.likes.all():
if like == request.user:
is_like = True
break
if not is_like:
post.likes.add(request.user)
notification = Notification.objects.create(notification_type=1, from_user=request.user, to_user=post.author, post=post)
if is_like:
post.likes.remove(request.user)
next = request.POST.get('next', '/')
return HttpResponseRedirect(next)
class AddDislike(LoginRequiredMixin, View):
def post(self, request, pk, *args, **kwargs):
post = Post.objects.get(pk=pk)
is_like = False
for like in post.likes.all():
if like == request.user:
is_like = True
break
if is_like:
post.likes.remove(request.user)
is_dislike = False
for dislike in post.dislikes.all():
if dislike == request.user:
is_dislike = True
break
if not is_dislike:
post.dislikes.add(request.user)
if is_dislike:
post.dislikes.remove(request.user)
next = request.POST.get('next', '/')
return HttpResponseRedirect(next)
class AddCommentLike(LoginRequiredMixin, View):
def post(self, request, pk, *args, **kwargs):
comment = Comment.objects.get(pk=pk)
is_dislike = False
for dislike in comment.dislikes.all():
if dislike == request.user:
is_dislike = True
break
if is_dislike:
comment.dislikes.remove(request.user)
is_like = False
for like in comment.likes.all():
if like == request.user:
is_like = True
break
if not is_like:
comment.likes.add(request.user)
notification = Notification.objects.create(notification_type=1, from_user=request.user, to_user=comment.author, comment=comment)
if is_like:
comment.likes.remove(request.user)
next = request.POST.get('next', '/')
return HttpResponseRedirect(next)
class AddCommentDislike(LoginRequiredMixin, View):
def post(self, request, pk, *args, **kwargs):
comment = Comment.objects.get(pk=pk)
is_like = False
for like in comment.likes.all():
if like == request.user:
is_like = True
break
if is_like:
comment.likes.remove(request.user)
is_dislike = False
for dislike in comment.dislikes.all():
if dislike == request.user:
is_dislike = True
break
if not is_dislike:
comment.dislikes.add(request.user)
if is_dislike:
comment.dislikes.remove(request.user)
next = request.POST.get('next', '/')
return HttpResponseRedirect(next)
class SharedPostView(View):
def post(self, request, pk, *args, **kwargs):
original_post = Post.objects.get(pk=pk)
form = ShareForm(request.POST)
if form.is_valid():
new_post = Post(
shared_body=self.request.POST.get('body'),
body=original_post.body,
author=original_post.author,
created_on=original_post.created_on,
shared_user=request.user,
shared_on=timezone.now(),
)
new_post.save()
for img in original_post.image.all():
new_post.image.add(img)
new_post.save()
return redirect ('post-list')
class UserSearch(View):
def get(self, request, *args, **kwargs):
query = self.request.GET.get('query')
profile_list = UserProfile.objects.filter(
Q(user__username__icontains=query)
)
context = {
'profile_list': profile_list,
}
return render(request, 'social/search.html', context)
class ListFollowers(View):
def get(self, request, pk, *args, **kwargs):
profile = UserProfile.objects.get(pk=pk)
followers = profile.followers.all()
context = {
'profile': profile,
'followers': followers,
}
return render(request, 'social/followers_list.html', context)
class PostNotification(View):
def get(self, request, notification_pk, post_pk, *args, **kwargs):
notification = Notification.objects.get(pk=notification_pk)
post = Post.objects.get(pk=post_pk)
notification.user_has_seen = True
notification.save()
return redirect('post-detail', pk=post_pk)
class FollowNotification(View):
def get(self, request, notification_pk, profile_pk, *args, **kwargs):
notification = Notification.objects.get(pk=notification_pk)
profile = UserProfile.objects.get(pk=profile_pk)
notification.user_has_seen = True
notification.save()
return redirect('profile', pk=profile_pk)
class ThreadNotification(View):
def get(self, request, notification_pk, object_pk, *args, **kwargs):
notification = Notification.objects.get(pk=notification_pk)
thread = ThreadModel.objects.get(pk=object_pk)
notification.user_has_seen = True
notification.save()
return redirect('thread', pk=object_pk)
class RemoveNotification(View):
def delete(self, request, notification_pk, *args, **kwargs):
notification = Notification.objects.get(pk=notification_pk)
notification.user_has_seen = True
notification.save()
return HttpResponse('Success', content_type='text/plain')
class ListThreads(View):
def get(self, request, *args, **kwargs):
threads = ThreadModel.objects.filter(Q(user=request.user) | Q(receiver=request.user))
context = {
'threads': threads
}
return render(request, 'social/inbox.html', context)
class CreateThread(View):
def get(self, request, *args, **kwargs):
form = ThreadForm()
context = {
'form': form
}
return render(request, 'social/create_thread.html', context)
def post(self, request, *args, **kwargs):
form = ThreadForm(request.POST)
username = request.POST.get('username')
try:
receiver = User.objects.get(username=username)
if ThreadModel.objects.filter(user=request.user, receiver=receiver).exists():
thread = ThreadModel.objects.filter(user=request.user, receiver=receiver)[0]
return redirect('thread', pk=thread.pk)
elif ThreadModel.objects.filter(user=receiver, receiver=request.user).exists():
thread = ThreadModel.objects.filter(user=receiver, receiver=request.user)[0]
return redirect('thread', pk=thread.pk)
if form.is_valid():
thread = ThreadModel(
user=request.user,
receiver=receiver
)
thread.save()
return redirect('thread', pk=thread.pk)
except:
messages.error(request, 'User not found')
return redirect('create-thread')
class ThreadView(View):
def get(self, request, pk, *args, **kwargs):
form = MessageForm()
thread = ThreadModel.objects.get(pk=pk)
message_list = MessageModel.objects.filter(thread__pk__contains=pk)
context = {
'thread': thread,
'form': form,
'message_list': message_list,
}
return render(request, 'social/thread.html', context)
class CreateMessage(View):
def post(self, request, pk, *args, **kwargs):
form = MessageForm(request.POST, request.FILES)
thread = ThreadModel.objects.get(pk=pk)
if thread.receiver == request.user:
receiver = thread.user
else:
receiver = thread.receiver
if form.is_valid():
message = form.save(commit=False)
message.thread = thread
message.sender_user = request.user
message.receiver_user = receiver
message.save()
notification = Notification.objects.create(
notification_type=4,
from_user=request.user,
to_user=receiver,
thread=thread
)
return redirect('thread', pk=pk)
models.py:
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class Post(models.Model):
shared_body = models.TextField(blank=True, null=True)
body = models.TextField()
image = models.ManyToManyField('Image', blank=True)
created_on = models.DateTimeField(default=timezone.now)
shared_on = models.DateTimeField(blank=True, null=True)
shared_user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, related_name='+')
author = models.ForeignKey(User, on_delete=models.CASCADE)
likes = models.ManyToManyField(User, blank=True, related_name='likes')
dislikes = models.ManyToManyField(User, blank=True, related_name='dislikes')
class Meta:
ordering = ['-created_on', '-shared_on']
class Comment(models.Model):
comment = models.TextField()
created_on = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey('Post', on_delete=models.CASCADE, null=True)
likes = models.ManyToManyField(User, blank=True, related_name='comment_likes')
dislikes = models.ManyToManyField(User, blank=True, related_name='comment_dislikes')
parent = models.ForeignKey('self', on_delete=models.CASCADE, blank=True, null=True, related_name='+')
#property
def children(self):
return Comment.objects.filter(parent=self).order_by('-created_on').all()
#property
def is_parent(self):
if self.parent is None:
return True
return False
class UserProfile(models.Model):
user = models.OneToOneField(User, primary_key=True, verbose_name='user', related_name='profile', on_delete=models.CASCADE)
name = models.CharField(max_length=30, blank=True, null=True)
bio = models.TextField(max_length=500, blank=True, null=True)
birth_date = models.DateField(null=True, blank=True)
location = models.CharField(max_length=100, blank=True, null=True)
picture = models.ImageField(upload_to='uploads/profile_pictures', default='uploads/profile_pictures/default.jpeg', blank=True)
followers = models.ManyToManyField(User, blank=True, related_name='followers')
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
class Notification(models.Model):
# 1 = Like, 2 = Comment, 3 = Follow, 4= DM
notification_type = models.IntegerField()
to_user = models.ForeignKey(User, related_name='notification_to', on_delete=models.CASCADE, null=True)
from_user = models.ForeignKey(User, related_name='notification_from', on_delete=models.CASCADE, null=True)
post = models.ForeignKey('Post', on_delete=models.CASCADE, related_name='+', blank=True, null=True)
comment = models.ForeignKey('Comment', on_delete=models.CASCADE, related_name='+', blank=True, null=True)
thread = models.ForeignKey('ThreadModel', on_delete=models.CASCADE, related_name='+', blank=True, null=True)
date = models.DateTimeField(default=timezone.now)
user_has_seen = models.BooleanField(default=False)
class ThreadModel(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='+')
receiver = models.ForeignKey(User, on_delete=models.CASCADE, related_name='+')
class MessageModel(models.Model):
thread = models.ForeignKey('ThreadModel', related_name='+', on_delete=models.CASCADE, blank=True, null=True)
sender_user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='+')
receiver_user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='+')
body = models.CharField(max_length=10000)
image = models.ImageField(upload_to='uploads/message_photos', blank=True, null=True)
date = models.DateTimeField(default=timezone.now)
is_read = models.BooleanField(default=False)
class Image(models.Model):
image = models.ImageField(upload_to='uploads/post_photos', blank=True, null=True)
Any tips as to why the news feed may only be appearing on the admin's account/ only appears AFTER a post has been submitted (which would be a nuisance to have to submit a post every time you want to view your news feed) would be greatly appreciated!
Does this issue occur even when you remove the filter:
posts = Post.objects.filter(
author__profile__followers__in=[logged_in_user.id]
).order_by('-created_on')
It looks like it only shows posts for the followers of the user.id
Firstfully, you should not end post() method with render. That may cause weird stuff happening during site loading. Rather use return self.form_valid(form) or the same with invalid. It's possibly, that you might need to inherit also FormMixin. Then you need to specify get_success_url() but I can see you know how to do that.
Secondly, if you want PostListView to be a list view, do it :) Then use get_queryset() method:
class PostListView(LoginRequiredMixin, ListView):
...
def get_queryset(self):
return Post.objects.filter(...)
Thirdly, I am not sure about author__profile__followers__in=[logged_in_user.id] filter. For me it is confusing. Maybe try different approach here to fix filtering. Try .all() instead of .filter() and see if it shows all correctly.
It seems you may be confused with ManyToMany relations. You should not use related name same as field name, it works exactly in a opposite way, as you might think. Read about it in Django's Docs.
Related
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 %}
Getting error 405 while using ModelFormMixin with DetailView
I want to create a DetailView page which displays the detail of a model but I want to add a Comment section in the DetailView page using ModelFormMixin. This is my views.py code: class PostDetailView(ModelFormMixin, DetailView): model = UserPost context_object_name='post_detail' form_class = UserCommentForm def get_context_data(self, *args, **kwargs): context = super(PostDetailView, self).get_context_data(*args, **kwargs) context['form'] = self.get_form() return context def get_absolute_url(self): return reverse(request, 'basic_app:post_detail', kwargs={'pk':self.pk}) But when I hit the submit button it shows the following error: Edited part: This is my views.py file model.py forms.py userpost_detail.html browser image before clicking enter button browser image after clicking enter button django admin page I'm sorry for not uploading the actual code because it was too difficult to upload that bulk of code.
I think the following code will help you. I code it a long time ago, but it seems to solve your problem (I didn't use taggit, so I created a PostTag model): Models: from django.db import models from django.contrib.auth.models import AbstractUser from django.utils.timezone import localtime from django.urls import reverse class User(AbstractUser): pass class PublishedManager(models.Manager): def get_queryset(self): return super().get_queryset().filter(status='published') class PostTag(models.Model): name = models.CharField(max_length=40) slug = models.SlugField(max_length=40) def __str__(self): return self.name class Post(models.Model): POST_STATUS = (('draft', 'Draft'), ('published', 'Published')) title = models.CharField(max_length=100) body = models.TextField() author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts') created = models.DateTimeField(auto_now_add=True) publish = models.DateTimeField(auto_now=True) updated = models.DateTimeField(auto_now=True) slug = models.SlugField(max_length=100, unique_for_date='publish') status = models.CharField(max_length=10, choices=POST_STATUS, default='draft') tags = models.ManyToManyField(PostTag, blank=True) def get_absolute_url(self): local_time = localtime(self.publish) return reverse("blog:post_date_detail", args=[local_time.year, local_time.month, local_time.day, self.slug]) class Meta: ordering = ('-publish',) def __str__(self): return self.title objects = models.Manager() # The default manager. published = PublishedManager() # Custom manager. class Comment(models.Model): post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments') name = models.CharField(max_length=80) email = models.EmailField() body = models.TextField() created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) active = models.BooleanField(default=True) def get_absolute_url(self): local_time = localtime(self.post.publish) return reverse("blog:post_date_detail", args=[local_time.year, local_time.month, local_time.day, self.post.slug]) class Meta: ordering = ('created',) def __str__(self): return f'Comment by {self.name} on {self.post}' Views: from django.shortcuts import render, get_object_or_404, HttpResponseRedirect from django.views.generic import ListView, DetailView, View from django.views.generic.edit import FormView, SingleObjectMixin, CreateView from django.views.generic.dates import YearArchiveView, MonthArchiveView, DateDetailView from django.core.mail import send_mail from django.db.models import Count from .models import Post, User, Comment, PostTag from .forms import EmailPostForm, CommentForm class PostListView(ListView): queryset = Post.published.all() context_object_name = 'posts' paginate_by = 4 def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # si hay kwargs se actualiza el context if self.kwargs: context["tag"] = self.kwargs['tag_slug'] return context def get_queryset(self): tag = None if self.kwargs: tag_slug = self.kwargs['tag_slug'] tag = get_object_or_404(PostTag, slug=tag_slug) posts = self.queryset.filter(tags__in=[tag]) return posts return self.queryset class PostYearArchiveView(YearArchiveView): queryset = Post.published.all() template_name = 'blog/post_list.html' date_field = "publish" context_object_name = 'posts' make_object_list = True paginate_by = 4 class PostMonthArchiveView(MonthArchiveView): queryset = Post.published.all() template_name = 'blog/post_list.html' date_field = "publish" context_object_name = 'posts' month_format='%m' paginate_by = 4 class PostDateDetailView(DateDetailView): queryset = Post.published.all() date_field = "publish" month_format='%m' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) obj = self.get_object() post_tags_pks = obj.tags.all().values_list('pk', flat=True) related_posts = self.queryset.filter(tags__in=post_tags_pks).exclude(pk=obj.pk) related_posts = related_posts.annotate(same_tags=Count('tags')).order_by('-same_tags','-publish')[:3] context["related_posts"] = related_posts comments = obj.comments.filter(active=True) context["comments"] = comments context['post_id'] = obj.pk context['form'] = CommentForm() return context class NewComment(CreateView): model = Comment template_name = 'blog/post_detail.html' form_class = CommentForm def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) post = context["form"].instance.post context['post'] = post post_tags_pks = post.tags.all().values_list('pk', flat=True) related_posts = Post.published.filter(tags__in=post_tags_pks).exclude(pk=post.pk) related_posts = related_posts.annotate(same_tags=Count('tags')).order_by('-same_tags','-publish')[:3] context["related_posts"] = related_posts comments = post.comments.filter(active=True) context["comments"] = comments return context class PostDetail(View): def get(self, request, *args, **kwargs): view = PostDateDetailView.as_view() return view(request, *args, **kwargs) def post(self, request, *args, **kwargs): view = NewComment.as_view() return view(request, *args, **kwargs) class SharePostView(SingleObjectMixin, FormView): form_class = EmailPostForm template_name = 'blog/post_share.html' success_url = '/blog' context_object_name = 'posts' queryset = Post.published.all() def get(self, request, *args, **kwargs): post = self.get_object() context = {'post': post, 'form': self.form_class} return render(request, self.template_name, context) def form_valid(self, form): post = self.get_object() post_url = self.request.build_absolute_uri(post.get_absolute_url()) form.send_mail(post, post_url) return super(SharePostView, self).form_valid(form) Considerations: See get_context_data to add other data to the context: in this case tags, related_post, the form, etc... I have used 3 views. DateDetailView (similar to your DetailView) to display the page (with the context needed). CreateView to manage the POST method and save the comment into the DB. I have also added context to get the post information. Finally a View with the intention of managing the same URL,but calling the appropiate view when the request is GET or POST. See urls.py URLS: from django.urls import path from blog import views from blog.models import Post app_name = 'blog' urlpatterns = [ path("", views.PostListView.as_view(), name="post_list"), path('tag/<slug:tag_slug>/', views.PostListView.as_view(), name='post_list_by_tag'), path('<int:year>/', views.PostYearArchiveView.as_view(), name="post_year_archive"), path('<int:year>/<int:month>/', views.PostMonthArchiveView.as_view(), name="post_month_numeric"), path('<int:year>/<int:month>/<int:day>/<slug:slug>/', views.PostDetail.as_view(), name="post_date_detail"), path('<int:pk>/share/', views.SharePostView.as_view(), name='post_share'), ] Comment form: class CommentForm(forms.ModelForm): class Meta: model = Comment fields = ('name', 'email', 'body', 'post') widgets = { 'name': forms.TextInput(attrs={'placeholder': 'Name'}), 'email': forms.EmailInput(attrs={'placeholder': 'E-mail'}), 'body': forms.Textarea(attrs={'placeholder': 'Write your message here'}), 'post' : forms.HiddenInput(), } form in template: <form method="post" action="" novalidate> {% csrf_token %} <div class="input-group input-group-icon"> {{ form.name }} <div class="input-icon"><i class="fas fa-user"></i></div> {% if form.name.errors %} {{form.name.errors}} {% endif %} </div> <div class="input-group input-group-icon"> {{form.email }} <div class="input-icon"> <i class="fas fa-envelope"></i> </div> {% if form.email.errors %} {{form.email.errors}} {% endif %} </div> <div class="msg"> <div class="input-group">{{form.body}} {% if form.body.errors %} {{form.body.errors}} {% endif %} </div> </div> <input type="hidden" name="post" value="{{ post.pk }}"> <div class="input-group send-reset"> <input type="submit" value="Enviar Comentario" /> </div> </form> Considerations: See the input type=hidden to get the post.pk. This is needed to save the comment.post field. I think I covered all the issues you can have. Hope it helps!!
How I can upload file in django?
I'm trying to upload file in a specific folder and store its path in DB through forms(CBV), but it doesn't work!! this is my code (forms, models, views, template). I'm selecting the file through forms then I submit the form, but it doesn't submit. #views.py class PostCreateView(LoginRequiredMixin, CreateView): model = Post # fields = ['title', 'content'] success_url = reverse_lazy('blog/new_post.html') template_name = 'blog/new_post.html' form_class = PostCreateForm def post(self, request, *args, **kwargs): form = self.form_class(request.POST, request.FILES) if form.is_valid(): form.save() return redirect(self.success_url) else: return render(request, self.template_name, {'form': form}) def form_valid(self, form): form.instance.author = self.request.user return super().form_valid(form) #model.py class Post(models.Model): title = models.CharField(max_length=1000) content = models.TextField() xml_file = models.FileField(null=True, upload_to='xml_files') rate = models.FloatField(null=True, blank=True, default=None) post_date = models.DateTimeField(default=timezone.now) post_update = models.DateTimeField(auto_now=True) author = models.ForeignKey(User, on_delete=models.CASCADE) def __str__(self): return self.title def get_absolute_url(self): # return '/detail/{}'.format(self.pk) return reverse('detail', args=[self.pk]) class Meta: ordering = ('-post_date', ) #forms.py class PostCreateForm(forms.ModelForm): title = forms.CharField( max_length=1000) content = forms.CharField(widget=forms.Textarea( attrs={'rows': 15, 'placeholder': 'write here'} ), max_length=50000) xml_file = forms.FileField(label='upload file') class Meta: model = Post fields = ['title', 'content', 'xml_file', ] #new_post.html {% block content %} {% load crispy_forms_tags %} <div class="border p-4 mb-5"> <legend class="border-bottom pb-1 mb-3">new post</legend> <form method="POST"> {% csrf_token %} {{form|crispy}} <input class="btn btn-secondary mt-4" type="submit" value="post"> </form> </div> {% endblock content %}
When you are uploading media like what you've got, it is necessary to add the following part to your <form>: enctype=multipart/form-data
Forms only showing up after submit button is clicked
I've checked similar posts about forms not showing up at all and I've tried applying the fixes, but it did not fix it for me. I have the following: stocks.html: <form method="post" class="form-inline my-2 my-lg-0"> {% csrf_token %} {{ symbol_form }} <button class="btn btn-secondary my-2 my-sm-0" type="submit">Add Stock</button> </form> views.py: class PortfolioStockListView(ListView): model = StockPortfolio template_name = 'stocks.html' def post(self, request): symbol_form = StockSymbolForm(request.POST) if request.method == 'POST': if symbol_form.is_valid(): model_instance = symbol_form.save(commit=False) model_instance.timestamp = timezone.now() model_instance.save() return redirect('/') else: return render(request, 'stocks.html', {'symbol_form': symbol_form}) else: symbol_form = StockSymbolForm() return render(request, 'stocks.html', {'symbol_form': symbol_form}) forms.py: class StockSymbolForm(ModelForm): class Meta: model = StockPortfolio fields = ['username', 'stock_symbol' , 'stock_qty'] models.py: class StockPortfolioUser(models.Model): username = models.OneToOneField(User, on_delete=models.CASCADE) usercash = models.PositiveIntegerField(default=100000) class StockPortfolio(models.Model): username = models.ForeignKey(StockPortfolioUser, on_delete=models.CASCADE) stock_symbol = models.CharField(max_length=5) stock_qty = models.PositiveIntegerField(default=0) How to fix the issue that is causing the forms to hide until the button is clicked? I can share more code from other files if necessary.
Pass it to your template overwriting get_context_data method class PortfolioStockListView(ListView): model = StockPortfolio template_name = 'stocks.html' def get_context_data(self, *, object_list=None, **kwargs): context = super(PortfolioStockListView, self).get_context_data(object_list=object_list, **kwargs) context['symbol_form'] = StockSymbolForm() return context def post(self, request): ...
django image upload forms
I am having problems with django forms and image uploads. I have googled, read the documentations and even questions ere, but cant figure out the issue. Here are my files my models class UserProfile(User): """user with app settings. """ DESIGNATION_CHOICES=( ('ADM', 'Administrator'), ('OFF', 'Club Official'), ('MEM', 'Ordinary Member'), ) onames = models.CharField(max_length=30, blank=True) phoneNumber = models.CharField(max_length=15) regNo = models.CharField(max_length=15) designation = models.CharField(max_length=3,choices=DESIGNATION_CHOICES) image = models.ImageField(max_length=100,upload_to='photos/%Y/%m/%d', blank=True, null=True) course = models.CharField(max_length=30, blank=True, null=True) timezone = models.CharField(max_length=50, default='Africa/Nairobi') smsCom = models.BooleanField() mailCom = models.BooleanField() fbCom = models.BooleanField() objects = UserManager() #def __unicode__(self): # return '%s %s ' % (User.Username, User.is_staff) def get_absolute_url(self): return u'%s%s/%s' % (settings.MEDIA_URL, settings.ATTACHMENT_FOLDER, self.id) def get_download_url(self): return u'%s%s/%s' % (settings.MEDIA_URL, settings.ATTACHMENT_FOLDER, self.name) ... class reports(models.Model): repID = models.AutoField(primary_key=True) repSubject = models.CharField(max_length=100) repRecepients = models.ManyToManyField(UserProfile) repPoster = models.ForeignKey(UserProfile,related_name='repposter') repDescription = models.TextField() repPubAccess = models.BooleanField() repDate = models.DateField() report = models.FileField(max_length=200,upload_to='files/%Y/%m/%d' ) deleted = models.BooleanField() def __unicode__(self): return u'%s ' % (self.repSubject) my forms from django import forms from django.http import HttpResponse from cms.models import * from django.contrib.sessions.models import Session from django.forms.extras.widgets import SelectDateWidget class UserProfileForm(forms.ModelForm): class Meta: model= UserProfile exclude = ('designation','password','is_staff', 'is_active','is_superuser','last_login','date_joined','user_permissions','groups') ... class reportsForm(forms.ModelForm): repPoster = forms.ModelChoiceField(queryset=UserProfile.objects.all(), widget=forms.HiddenInput()) repDescription = forms.CharField(widget=forms.Textarea(attrs={'cols':'50', 'rows':'5'}),label='Enter Report Description here') repDate = forms.DateField(widget=SelectDateWidget()) class Meta: model = reports exclude = ('deleted') my views #login_required def reports_media(request): user = UserProfile.objects.get(pk=request.session['_auth_user_id']) if request.user.is_staff== True: repmedform = reportsForm(request.POST, request.FILES) if repmedform.is_valid(): repmedform.save() repmedform = reportsForm(initial = {'repPoster':user.id,}) else: repmedform = reportsForm(initial = {'repPoster':user.id,}) return render_to_response('staffrepmedia.html', {'repfrm':repmedform, 'rep_media': reports.objects.all()}) else: return render_to_response('reports_&_media.html', {'rep_media': reports.objects.all()}) ... #login_required def settingchng(request): user = UserProfile.objects.get(pk=request.session['_auth_user_id']) form = UserProfileForm(instance = user) if request.method == 'POST': form = UserProfileForm(request.POST, request.FILES, instance = user) if form.is_valid(): form.save() return HttpResponseRedirect('/settings/') else: form = UserProfileForm(instance = user) if request.user.is_staff== True: return render_to_response('staffsettingschange.html', {'form': form}) else: return render_to_response('settingschange.html', {'form': form}) ... #login_required def useradd(request): if request.method == 'POST': form = UserAddForm(request.POST,request.FILES ) if form.is_valid(): password = request.POST['password'] request.POST['password'] = set_password(password) form.save() else: form = UserAddForm() return render_to_response('staffadduser.html', {'form':form}) Example of my templates {% if form.errors %} <ol> {% for field in form %} <H3 class="title"> <p class="error"> {% if field.errors %}<li>{{ field.errors|striptags }}</li>{% endif %}</p> </H3> {% endfor %} </ol> {% endif %} <form method="post" id="form" action="" enctype="multipart/form-data" class="infotabs accfrm"> {{ repfrm.as_p }} <input type="submit" value="Submit" /> </form>
the issue was actually that this line <form method="post" id="form" action="" enctype="multipart/form-data" class="infotabs accfrm"> appeared as <form method="post" id="form" action="" enctype="multipart/form -data" class="infotabs accfrm"> hence the forms were not uploading. And to think I have had this issue for 2 weeks. If its ok with you guys, i will delete this question.