Issue
Django beginner here.
I am trying to make a an app for where users can make connections, post stuff, chat, etc. There are two user types - Parents
and Child
. For this I extended the AbstractBaseUser
model and created two another models - Parent
and Child
with a OneToOne
link to the User
.
#accounts/models.py
class User(AbstractBaseUser, PermissionsMixin):
REQUIRED_FIELDS = []
EMAIL_FIELD = "email"
USERNAME_FIELD = 'email'
objects = UserManager()
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=DefaultModel.MAX_LENGTH, unique=False)
last_name = models.CharField(max_length=DefaultModel.MAX_LENGTH, unique=False)
profile_photo = models.ImageField(default='uploads/profile/default_profile.jpg', upload_to=content_image_name)
cover_photo = models.ImageField(default='uploads/profile/default_cover.jpg', upload_to=content_image_name)
username = AutoSlugField(populate_from='first_name', unique=True, sep='.')
bio = models.CharField(max_length=255, blank=True, default="Nothing to see here !")
is_child = models.BooleanField(default=False)
is_parent = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
# storing timestamps for users.
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
CHOICES = (('M','Male'),('F','Female'),('O','Other'))
gender = models.CharField(max_length=10, choices=CHOICES)
def get_absolute_url(self):
return "/users/{}".format(self.username)
def __str__(self):
return "{} {}".format(self.first_name, self.last_name)
class Child(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
friends = models.ManyToManyField('self',
blank=True,
related_name='friends',
db_column='friends',)
def __str__(self):
return "{} {}".format(self.user.first_name, self.user.last_name)
class Parent(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
connections = models.ManyToManyField('self',
blank=True,
related_name='connections',
db_column='connections',)
def __str__(self):
return "{} {}".format(self.user.first_name, self.user.last_name)
As you can see a Child
can only be a friend with another Child
and a Parent
can only connect with a Parent
.
Basically I have two apps - Feeds for handling posts and accounts for handling accounts. There is a page for displaying the current users (/childs/
for Child
and /parents/
for Parent
) and another for friends (/friends/
for Child
and /connections/
for Parent
).
In the homepage (/home
) of the apps there are two sidebars - one for showing users whom the request.user
can send friend request to and another for displaying the friends of request.user
. Since there is a single url (/home
) for both user types, therefore the strategy is :
- Make a base ListView for displaying both current users and friends.
- Inherit it for the individual users and friends page.
- Inherit it for
home.html
for/home
.
@method_decorator(login_required, name='dispatch')
class UserList(ListView):
model = User
def get_context_data(self, *args, **kwargs):
context = super(UserList, self).get_context_data(**kwargs)
if self.request.user.is_child:
childs = Child.objects.exclude(user=self.request.user.child)
sent_requests = ChildFriendRequest.objects.filter(from_user=self.request.user.child)
recv_requests = ChildFriendRequest.objects.filter(to_user=self.request.user.child)
friends = self.request.user.child.friends.all()
recv_from = [i.from_user for i in recv_requests]
users = [i for i in childs if i not in friends and i not in recv_from]
sent_to = [ i.to_user for i in sent_requests]
context['users'] = users
context['sent'] = sent_to
context['friends'] = friends
context['recv_requests'] = recv_requests
elif self.request.user.is_parent:
parents = Parent.objects.exclude(user=self.request.user.parent)
sent_requests = ParentConnectionRequest.objects.filter(from_user=self.request.user.parent)
recv_requests = ParentConnectionRequest.objects.filter(to_user=self.request.user.parent)
connections = self.request.user.parent.connections.all()
recv_from = [i.from_user for i in recv_requests]
users = [i for i in parents if i not in connections and i not in recv_from]
sent_to = [ i.to_user for i in sent_requests]
context['users'] = users
context['sent'] = sent_to
context['connections'] = connections
context['recv_requests'] = recv_requests
return context
class ChildList(UserList):
template_name = "account/child/childs_list.html"
class FriendList(UserList):
template_name = "account/child/friend_list.html"
class ParentList(UserList):
template_name = "account/parent/parent_list.html"
class ConnectionList(UserList):
template_name = "account/parent/connection_list.html"
class Sidebar(UserList):
template_name = "feeds/home.html"
Now views
of Feeds
app also use home.html
for it displaying feeds.
class PostListView(ListView):
model = Post
template_name = 'feeds/home.html'
context_object_name = 'posts'
ordering = ['-date_posted']
paginate_by = 10
def get_context_data(self, **kwargs):
context = super(PostListView, self).get_context_data(**kwargs)
if self.request.user.is_authenticated:
liked = [i for i in Post.objects.all() if Like.objects.filter(user = self.request.user, post=i)]
context['liked_post'] = liked
return context
The problem here is that whenever /friends
or /childs
is accessed I can see the users but in the /home
no user is shown although I can see the posts.
Here's home.html
{% extends "feeds/layout.html" %}
{% load static %}
{% block friends_sidebar %}
<div class="widget stick-widget">
<h4 class="widget-title">People Nearby</h4>
<ul class="followers">
{% if users %}
{% for user_p in users %}
<li>
<figure>
<a href="{{ user_p.user.get_absolute_url }}" title=""><img src="{{ user_p.user.profile_photo.url }}" width="40" height="40" alt=""></a>
</figure>
<div class="friend-meta">
<h4><a href="{{ user_p.user.get_absolute_url }}" title="">{{ user_p.user }}</a></h4>
{% if not user_p in sent %}
<a href="/child/friend-request/send/{{ user_p.user.id }}/" title="" class="underline">Add Friend</a>
{% else %}
<a href="/child/friend-request/cancel/{{ user_p.user.id }}/" title="" class="underline">Cancel Request</a>
{% endif %}
</div>
</li>
{% endfor %}
{% else %}
<p>No one is here !</p>
{% endif %}
</ul>
</div>
{% endblock %}
I can only see :
No one is here !
So the question is how can I go working around this ? Is it because two views are using the same template ?
I am using Django 3.2.9 and Python 3.8.
Solution
As @Razenstein mentioned I needed to have the contexts of UserList in PostListView, so I inherited UserList in PostListView and that did it. Here's what was to be done :
class PostListView(UserListView):
model = Post
template_name = 'feeds/home.html'
context_object_name = 'posts'
ordering = ['-date_posted']
paginate_by = 10
def get_context_data(self, **kwargs):
context = super(PostListView, self).get_context_data(**kwargs)
if self.request.user.is_authenticated:
liked = [i for i in Post.objects.all() if Like.objects.filter(user = self.request.user, post=i)]
context['liked_post'] = liked
return context
The key here is to inherit the UserList
class and use super()
in get_context_data()
.
Answered By - Taufeeque Sifat
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.