DJango - два разных представления из разных приложений в одном шаблоне

Здесь начинающий Джанго.

Я пытаюсь сделать приложение, в котором пользователи могут устанавливать связи, размещать материалы, общаться в чате и т.д. Есть два типа пользователей - Parents и Child. Для этого я расширил модель AbstractBaseUser и создал две другие модели - Parent и Child с OneToOne ссылкой на 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)

Как вы видите, Child может быть другом только с другим Child, а Parent может подключиться только с Parent. В основном у меня есть два приложения - Feeds для работы с постами и Accounts для работы с аккаунтами. Есть страница для отображения текущих пользователей (/childs/ для Child и /parents/ для Parent) и другая для друзей (/friends/ для Child и /connections/ для Parent).

На главной странице (/home) приложения есть две боковые панели - одна для показа пользователей, которым request.user может отправить запрос на дружбу, а другая для показа друзей request.user. Поскольку для обоих типов пользователей существует один url (/home), поэтому стратегия такова :

  1. Make a base ListView for displaying both current users and friends.
  2. Inherit it for the individual users and friends page.
  3. 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"

Теперь views приложения Feeds также используют home.html для отображения фидов.

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

Проблема в том, что при обращении к /friends или /childs я вижу пользователей, но в /home пользователь не отображается, хотя я вижу сообщения.

Вот 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 %}

Я могу только видеть :

No one is here !

Итак, вопрос в том, как я могу обойти это? Это потому, что два представления используют один и тот же шаблон?

Я использую Django 3.2.9 и Python 3.8.

Как упомянул @Razenstein, мне нужно было иметь контексты UserList в PostListView, поэтому я унаследовал UserList в PostListView, и это помогло. Вот что нужно было сделать :

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

Ключом здесь является наследование класса UserList и использование super() в get_context_data().

Вернуться на верх