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.
I am working on an Auction website using Django. I am trying to display data of the Last_bid field which is connected to Bid table with a foreign key. I tried many ways but nothing worked out.
The models.py file is:
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.db.models.base import Model
from django.db.models.deletion import CASCADE
from django.db.models.fields import CharField
from django.utils import timezone
class User(AbstractUser):
pass
class Category(models.Model):
category = models.CharField(max_length=64)
def __str__(self):
return f'{self.category}'
class AuctionListing(models.Model):
item_name = models.CharField(max_length=100)
item_image = models.ImageField(upload_to="products", null=True, blank=True)
detail = models.TextField()
price = models.IntegerField()
last_bid = models.ForeignKey('Bid', on_delete=models.CASCADE, blank=True, null=True, related_name='lst')
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='publisher_listing', null=True, blank=True)
watchers = models.ManyToManyField(User, blank=True, related_name='watched_list')
pub_date = models.DateTimeField(auto_now=True, null=True)
deadline = models.DateTimeField(null=True)
list_category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, related_name='sortion')
closed = models.BooleanField(default=False)
def __str__(self):
return f'{self.item_name} - {self.price}'
class Bid(models.Model):
bid = models.IntegerField()
user = models.ForeignKey(User, on_delete=CASCADE)
auction = models.ForeignKey(AuctionListing, on_delete=CASCADE)
bid_date = models.DateTimeField(auto_now=True)
def __str__(self):
return f'{self.bid}-{self.auction}'
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=CASCADE)
com = models.TextField()
pub_date = models.DateField()
com_item = models.ForeignKey(AuctionListing, on_delete=models.CASCADE, related_name='get_comment')
def __str__(self):
return f'{self.user} - {self.pub_date}'
Views.py:
from django.contrib.auth import authenticate, login, logout
# from django.contrib.auth.decorators import login_required
from django.db import IntegrityError, reset_queries
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import redirect, render
from django.urls import reverse
from django.forms import ModelForm
from .models import *
def index(request):
active_list = AuctionListing.objects.all().order_by('id').reverse()
return render(request, "auctions/index.html", {'active_list': active_list })
def login_view(request):
if request.method == "POST":
# Attempt to sign user in
username = request.POST["username"]
password = request.POST["password"]
user = authenticate(request, username=username, password=password)
# Check if authentication successful
if user is not None:
login(request, user)
return HttpResponseRedirect(reverse("index"))
else:
return render(request, "auctions/login.html", {
"message": "Invalid username and/or password."
})
else:
return render(request, "auctions/login.html")
def logout_view(request):
logout(request)
return HttpResponseRedirect(reverse("index"))
def register(request):
if request.method == "POST":
username = request.POST["username"]
email = request.POST["email"]
# Ensure password matches confirmation
password = request.POST["password"]
confirmation = request.POST["confirmation"]
if password != confirmation:
return render(request, "auctions/register.html", {
"message": "Passwords must match."
})
# Attempt to create new user
try:
user = User.objects.create_user(username, email, password)
user.save()
except IntegrityError:
return render(request, "auctions/register.html", {
"message": "Username already taken."
})
login(request, user)
return HttpResponseRedirect(reverse("index"))
else:
return render(request, "auctions/register.html")
class CreateForm(ModelForm):
class Meta:
model = AuctionListing
fields = ['item_name', 'item_image', 'detail', 'price', 'deadline', 'list_category']
def create_listing(request):
user = request.user
if user.id is None:
return redirect('login')
if request.method == 'GET':
context = {
'form': CreateForm()
}
return render(request, 'auctions/create_listing.html', context)
else:
if request.method == 'POST':
form = CreateForm(request.POST or None, request.FILES or None)
if form.is_valid():
item_name = form.cleaned_data['item_name']
item_image = form.cleaned_data['item_image']
detail = form.cleaned_data['detail']
price = form.cleaned_data['price']
deadline = form.cleaned_data['deadline']
list_category = form.cleaned_data['list_category']
listing_created = AuctionListing.objects.create(
item_name = item_name,
item_image = item_image,
detail = detail,
price = price,
deadline = deadline,
list_category = list_category,
user = request.user,
)
listing_created.save()
return redirect('index')
def listing(request, pk):
user = request.user
list = AuctionListing.objects.get(id=pk)
if request.method == 'POST':
bid = request.POST.get('placebid')
user = request.user
form = Bid(bid=bid, user=user, auction=list)
form.save()
return render(request, 'auctions/listing.html', {'list': list})
The index.html is:
{% extends "auctions/layout.html" %}
{% block body %}
<h2>Active Listings</h2>
{% for each in active_list %}
<div class="back">
<div class="imag">
<img src="{{ each.item_image.url }}" alt="">
</div>
<div class="detail">
<h1>{{ each.item_name }}</h1>
<h6>Published by: <span>{{ each.user }}</span></h6>
{% if each.last_bid %}
<p>Current Bid: <span>{{ each.last_bid.bid }} </span></p>
{% else %}
<p>Current Bid: <span>{{ each.price }} </span></p>
{% endif %}
<p>Published date: <span>{{ each.pub_date }}</span></p>
<p>DeadLine: <span>{{ each.deadline }}</span></p>
<div class="bid-detail">
<p>Initial Price: {{ each.price }}</p>
<p>Watchers: 10</p>
</div>
</div>
</div>
{% endfor %}
{% endblock %}
I want to display the last_bid in index.html but I was not able to. Please help me with this problem. I will be thankful to you.
I have been trying to implement a follow/unfollow system on django in which a user can follow other users and the user can also be followed, in the user's profile there is a following count which displays how many people the user is following and a follower count which is supposed to display how many followers the user has just like in instagram. Everything is working good except for the follower count which doesn't counting the followers. for doing this follower count, I used signals but it doesnt work. How can I fix this problem?
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
profile_pic = models.ImageField(upload_to='profile_pics', null=True, blank=True, default='default.png')
bio = models.CharField(max_length=400, default=1, null=True)
connection = models.CharField(max_length = 100, blank=True)
follower = models.IntegerField(default=0)
following = models.IntegerField(default=0)
def __str__(self):
return f'{self.user.username} Profile'
class Following(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
followed = models.ManyToManyField(User, related_name="followed")
follower = models.ManyToManyField(User, related_name="follower")
#classmethod
def follow(cls, user, another_account):
obj, create = cls.objects.get_or_create(user = user)
obj.followed.add(another_account)
print("followed")
#classmethod
def unfollow(cls, user, another_account):
obj, create = cls.objects.get_or_create(user = user)
obj.followed.remove(another_account)
print("unfollowed")
def __str__(self):
return f'{self.user.username} Profile'
views.py
def profile(request, username=None):
profile, created = Profile.objects.get_or_create(user=request.user)
if username:
post_owner = get_object_or_404(User, username=username)
profile_bio = Profile.objects.filter(user_id=post_owner)
user_posts = Post.objects.filter(user_id=post_owner)
user = User.objects.get(username=username)
is_following = Following.objects.filter(user=request.user, followed=user)
following_obj = Following.objects.get(user=user)
follower = following_obj.follower.count()
following = following_obj.followed.count()
else:
post_owner = request.user
user_posts = Post.objects.filter(user=request.user)
profile_bio = Profile.objetcs.filter(user=request.user)
args1 = {
'post_owner': post_owner,
'user_posts': user_posts,
'follower': follower,
'following': following,
'connection': is_following,
'profile_bio': profile_bio,
}
return render(request, 'profile.html', args1)
def follow(request, username):
main_user = request.user
to_follow = User.objects.get(username=username)
following = Following.objects.filter(user = main_user, followed = to_follow)
is_following = True if following else False
if is_following:
Following.unfollow(main_user, to_follow)
is_following = False
else:
Following.follow(main_user, to_follow)
is_following = True
resp = {
'following': is_following,
}
response = json.dumps(resp)
return HttpResponse(response, content_type="application/json")
signals.py
#receiver(m2m_changed, sender = Following.followed.through) # which list is changed
def add_follower(sender, instance, action, reverse, pk_set, **kwargs):
followed_users = [] # list of users main (logged ) user have followed
logged_user = User.objects.get(username = instance) # user who followed other users
for i in pk_set:
user = User.objects.get(pk = i)
following_obj = Following.objects.get(user = user)
followed_users.append(following_obj)
if action == "pre_add":
for i in followed_users:
i.follower.add(logged_user)
i.save()
if action == "pre_remove":
for i in followed_users:
i.follower.remove(logged_user)
i.save()
profile.html
{% if connection and not request.user == post_owner %}
<a type="button" class="button-caballo" id="follow" role="button" href="{% url 'follow' post_owner.username %}">Unfollow</a>
{% elif not connection and not request.user == post_owner %}
<a type="button" class="button-caballo" id="follow" role="button" href="{% url 'follow' post_owner.username %}">Follow</a>
{% endif %}
<div class="header-item">
{{follower}}
</div>
<div class="header-item">
{{following}}
</div>
why creating another field for the followers? you can get the followers count and users from the same Following table without any need for followers field.
your following model should only contain user, followed
you can get the followers by using
following.objects.filter(followed=request.user)
I have been trying make users follow other users from thier posts like in instagrams explore page. Currently a user can just follow and unfollow other users from their profile but I will like to have that follow/unfollow on their posts too. I tried to make this happen but in the process I got a NameError name 'username' is not defined, How can I fix this error in order to make this work?
models.py (mates model is where the follow/unfollow should go)
class Mates(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='usermates', unique=True)
req_bio = models.CharField(max_length=400)
class Following(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
followed = models.ManyToManyField(User, related_name="followed")
follower = models.ManyToManyField(User, related_name="follower")
#classmethod
def follow(cls, user, another_account):
obj, create = cls.objects.get_or_create(user = user)
obj.followed.add(another_account)
print("followed")
#classmethod
def unfollow(cls, user, another_account):
obj, create = cls.objects.get_or_create(user = user)
obj.followed.remove(another_account)
print("unfollowed")
def __str__(self):
return f'{self.user.username} Profile'
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
profile_pic = models.ImageField(upload_to='profile_pics', null=True, blank=True, default='default.png')
bio = models.CharField(max_length=400, default=1, null=True)
connection = models.CharField(max_length = 100, blank=True)
follower = models.IntegerField(default=0)
following = models.IntegerField(default=0)
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
img = Image.open(self.profile_pic.path)
if img.height > 300 or img.width > 300:
output_size = (300,300)
img.thumbnail(output_size)
img.save(self.profile_pic.path)
def __str__(self):
return f'{self.user.username} Profile'
views.py
def matesmain(request):
if request.user.has_posts():
contents = Mates.objects.filter(
categories__in=['action', 'sports', 'shooter', 'battle_royale', 'adventure', 'racing']
)
mates_owner = get_object_or_404(User, username=username)
context = {
'contents': contents,
'mates_owner': mates_owner,
}
print("nice3")
return render(request, 'mates.html', context)
else:
return render(request, 'mates-error.html')
def follow(request, username):
main_user = request.user
to_follow = User.objects.get(username=username)
following = Following.objects.filter(user = main_user, followed = to_follow)
is_following = True if following else False
if is_following:
Following.unfollow(main_user, to_follow)
is_following = False
else:
Following.follow(main_user, to_follow)
is_following = True
resp = {
'following': is_following,
}
response = json.dumps(resp)
return HttpResponse(response, content_type="application/json")
html
{% if connection and not request.user == mates_owner %}
<a type="button" class="button-caballo" id="follow" role="button" href="{% url 'follow' mates_owner.username %}">Unfollow</a>
{% elif not connection and not request.user == mates_owner %}
<a type="button" class="button-caballo" id="follow" role="button" href="{% url 'follow' mates_owner.username %}">Follow</a>
{% endif %}
urls.py
urlpatterns = [
path('follow/<str:username>', views.follow, name='follow')
path('mates-main', views.matesmain, name='mates-main'),
]
traceback
Traceback (most recent call last):
File "C:\Users\USER\Envs\startup\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\USER\Envs\startup\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\USER\Envs\startup\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\USER\startup\gstartup\startup_home\views.py", line 126, in matesmain
mates_owner = get_object_or_404(User, username=username)
NameError: name 'username' is not defined
[16/Jul/2020 08:53:25] "GET /mates-main HTTP/1.1" 500 70246
I am trying to add a follow sistem to my django project my when running my code, I am getting a The QuerySet value for an exact lookup must be limited to one result using slicing. error, It is saying that the wrong part is on this line of code of the views.py file following_obj = Following.objects.get(user=user).
views.py
def profile(request, username=None):
profile, created = Profile.objects.get_or_create(user=request.user)
if username:
post_owner = get_object_or_404(User, username=username)
user_posts = Profile.objects.filter(user_id=post_owner)
user = User.objects.filter(username=username)
is_following = Following.objects.filter(user=request.user, followed=user)
following_obj = Following.objects.get(user=user)
follower, following = following_obj.follower.count(), following_obj.followed.count()
else:
post_owner = request.user
user_posts = Profile.objects.filter(user=request.user)
args1 = {
'post_owner': post_owner,
'user_posts': user_posts,
'connection': is_following,
'follower': follower,
'following': following,
}
return render(request, 'profile.html', args1)
def follow(request, username):
main_user = request.user
to_follow = User.objects.get(username=username)
following = Following.objects.filter(user = main_user, followed = to_follow)
is_following = True if following else False
if is_following:
Following.unfollow(main_user, to_follow)
is_following = False
else:
Following.follow(main_user, to_follow)
is_following = True
resp = {
'following': is_following,
}
response = json.dumps(resp)
return HttpResponse(response, content_type="application/json")
models.py
class Profile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
profile_pic = models.ImageField(upload_to='profile_pics', null=True, blank=True, default='default.png')
bio = models.CharField(max_length=400, default=1, null=True)
follower = models.IntegerField(default=0)
following = models.IntegerField(default=0)
def __str__(self):
return f'{self.user.username} Profile'
class Following(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
followed = models.ManyToManyField(User, related_name="followed")
follower = models.ManyToManyField(User, related_name="follower")
#classmethod
def follow(cls, user, another_account):
obj, created = cls.objects.get(user = user)
obj.followed.add(another_account)
print("followed")
#classmethod
def unfollow(cls, user, another_account):
obj, create = cls.objects.get(user = user)
obj.followed.remove(another_account)
print("unfollowed")
def __str__(self):
return f'{self.user.username} Profile'
profile.html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
{% if connection and not request.user == post_owner %}
<a type="button" class="btn btn-outline-primary" id="follow" role="button" href="{% url 'follow' post_owner.username %}">Unfollow</a>
{% elif not connection and not request.user == post_owner %}
<a type="button" class="btn btn-outline-primary" id="follow" role="button" href="{% url 'follow' post_owner.username %}">Follow</a>
{% endif %}
<p>Follower : {{follower}} Following : {{following}}</p>
<script type="text/javascript">
$("#follow").click(function(e){
e.preventDefault();
var href = this.href;
$.ajax({
url : href,
success : function(response){
if(response["following"]){
$("#follow").html("Unfollow");
}
else{
$("#follow").html("Follow");
}
}
})
})
</script>
The line:
user = User.objects.filter(username=username)
returns a collection of User objects, you should retrieve a single one with .get(…) [Django-doc]:
user = User.objects.get(username=username)