Django - 来自不同应用程序的两个不同视图到一个模板中
Django - Two Different Views from Different Apps into a single Template
这里是 Django 初学者。
我正在尝试制作一个应用程序,供用户建立联系、post 东西、聊天等。有两种用户类型 - Parents
和 Child
。为此,我扩展了 AbstractBaseUser
模型并创建了另外两个模型 - Parent
和 Child
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
),因此策略是:
- 制作一个基础 ListView 以显示当前用户和好友。
- 为个人用户和好友页面继承。
- 为
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"
现在 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
中没有显示用户,尽管我可以看到 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
这里的关键是继承UserList
class,在get_context_data()
中使用super()
。
这里是 Django 初学者。
我正在尝试制作一个应用程序,供用户建立联系、post 东西、聊天等。有两种用户类型 - Parents
和 Child
。为此,我扩展了 AbstractBaseUser
模型并创建了另外两个模型 - Parent
和 Child
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
),因此策略是:
- 制作一个基础 ListView 以显示当前用户和好友。
- 为个人用户和好友页面继承。
- 为
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"
现在 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
中没有显示用户,尽管我可以看到 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
这里的关键是继承UserList
class,在get_context_data()
中使用super()
。