Django - 来自不同应用程序的两个不同视图到一个模板中

Django - Two Different Views from Different Apps into a single Template

这里是 Django 初学者。

我正在尝试制作一个应用程序,供用户建立联系、post 东西、聊天等。有两种用户类型 - ParentsChild。为此,我扩展了 AbstractBaseUser 模型并创建了另外两个模型 - ParentChild OneToOne link 到 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 建立联系。 基本上我有两个应用程序 - 用于处理 post 的提要和用于处理帐户的帐户。有一个用于显示当前用户的页面(/childs/ 用于 Child/parents/ 用于 Parent)和另一个用于朋友的页面(/friends/ 用于 Child /connections/ Parent).

在应用程序的主页 (/home) 中有两个侧边栏 - 一个用于显示 request.user 可以向其发送好友请求的用户,另一个用于显示 request.user 的好友].由于两种用户类型都有一个 url (/home),因此策略是:

  1. 制作一个基础 ListView 以显示当前用户和好友。
  2. 为个人用户和好友页面继承。
  3. home.html继承/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"

现在 viewsFeeds 应用也使用 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 中没有显示用户,尽管我可以看到 posts.

这里是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 提到的,我需要在 PostListView 中拥有 UserList 的上下文,所以我在 PostListView 中继承了 UserList 并做到了。这是要做的事情:

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

这里的关键是继承UserListclass,在get_context_data()中使用super()