如何在同一个基于 class 的视图下拥有两个单独的查询集 EX:用户个人资料和朋友
How to have two separate query-sets under the same class based view EX: User Profile and Friends
我之前问过一个问题:如何在同一个基于 class 的视图下拥有两个单独的查询集。由于语法错误,最初的问题很简单,但在修复它后我得到了 :get() got an unexpected keyword argument 'pk'
我认为这是我如何写我的观点的问题。
编辑:澄清问题:如何让两个查询集一个调用用户的 pk 信息,另一个在相同 class.
下制作用户列表
views.py
class ViewProfile(generic.ListView):
model = Post
template_name = 'accounts/profile.html'
def view_profile(request, pk=None):
if pk:
user = User.objects.get(pk=pk)
else:
user = request.user
kwargs = {'user': request.user}
return render(request, 'accounts/profile.html', kwargs)
def get(self, request):
users =User.objects.all()
object_list= Post.objects.filter(owner =self.request.user).order_by('-timestamp')
args ={'object_list':object_list,'users':users}
return render (request, self.template_name, args)
urls.py
# profilepage
url(r'^profile/$', views.ViewProfile.as_view(), name='view_profile'),
# profilepage
url(r'^profile/(?P<pk>\d+)/$', views.ViewProfile.as_view(), name='view_profile_with_pk'),
简介
<div class="col-md-4">
<h1>Friends</h1>
{%for user in users %}
<a href="{% url 'accounts:view_profile_with_pk' pk=user.pk %}">
<h3>{{user.username}}</h3>
</a>
{%endfor%}
</div>
你好,你可以这样试试吗
def view_profile(request, *args, **kwargs, pk=None):
if 'pk' in kwargs:
user = User.objects.get(pk=kwargs['pk'])
else:
user = request.user
kwargs = {'user': request.user}
return render(request, 'accounts/profile.html', kwargs)
如您所见,您的 view_profile_with_pk
url 模式采用 pk
参数:
url(r'^profile/(?P<pk>\d+)/$', views.ViewProfile.as_view(), name='view_profile_with_pk')
但是在您的 ViewProfile
视图中,您已将 get()
方法配置为:
def get(self, request):
# ...
你可以清楚地注意到get()
正好两个参数,即self
和request
。任何地方都没有 pk
。所以 Django 不知道。
还有。
您可以向 get()
函数添加 *args
和 **kwargs
参数,这将处理您的 url 参数:
def get(self, request, *args, **kwargs):
# ...
然后你可以在函数中自由获取你的 pk
:
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk') # <<<
users = User.objects.all()
object_list = Post.objects.filter(owner=request.user).order_by('-timestamp')
context = {'object_list': object_list, 'users': users}
return render(request, self.template_name, context)
但我不明白为什么你定义了 view_profile
函数,而你可以在 get()
函数中实现它的逻辑:
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
owner = User.objects.get(pk=pk) if pk else request.user # <<<
users = User.objects.all()
object_list = Post.objects.filter(owner=owner).order_by('-timestamp')
# ________________________________^
context = {'object_list': object_list, 'users': users}
return render(request, self.template_name, context)
这将起作用,直到您向视图提供不存在的 pk
。这将导致异常。您可以使用 get_object_or_404()
:
来解决这个问题
from django.shortcuts import get_object_or_404
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
owner = get_object_or_404(User, pk=pk) if pk else request.user # <<<
users = User.objects.all()
object_list = Post.objects.filter(owner=owner).order_by('-timestamp')
context = {'object_list': object_list, 'users': users}
return render(request, self.template_name, context)
现在您应该有一个功能齐全的视图。
编辑:
正如您刚才所说,视图 return 具有相同的 User
数据。这是因为:
users = User.objects.all()
这一行是没有意义的,因为每次用户向你的视图发送请求,他都会在context
中得到一个users
属性,它正好持有所有的用户在你的数据库中。
一个可能且更有意义的解决方案是将当前用户附加到此 属性:
# ...
context = {'object_list': object_list, 'user': owner}
# _______________________________________^
return render(request, self.template_name, context)
现在视图将 return Post
及其相关的 User
。
我之前问过一个问题:如何在同一个基于 class 的视图下拥有两个单独的查询集。由于语法错误,最初的问题很简单,但在修复它后我得到了 :get() got an unexpected keyword argument 'pk'
我认为这是我如何写我的观点的问题。
编辑:澄清问题:如何让两个查询集一个调用用户的 pk 信息,另一个在相同 class.
下制作用户列表views.py
class ViewProfile(generic.ListView):
model = Post
template_name = 'accounts/profile.html'
def view_profile(request, pk=None):
if pk:
user = User.objects.get(pk=pk)
else:
user = request.user
kwargs = {'user': request.user}
return render(request, 'accounts/profile.html', kwargs)
def get(self, request):
users =User.objects.all()
object_list= Post.objects.filter(owner =self.request.user).order_by('-timestamp')
args ={'object_list':object_list,'users':users}
return render (request, self.template_name, args)
urls.py
# profilepage
url(r'^profile/$', views.ViewProfile.as_view(), name='view_profile'),
# profilepage
url(r'^profile/(?P<pk>\d+)/$', views.ViewProfile.as_view(), name='view_profile_with_pk'),
简介
<div class="col-md-4">
<h1>Friends</h1>
{%for user in users %}
<a href="{% url 'accounts:view_profile_with_pk' pk=user.pk %}">
<h3>{{user.username}}</h3>
</a>
{%endfor%}
</div>
你好,你可以这样试试吗
def view_profile(request, *args, **kwargs, pk=None):
if 'pk' in kwargs:
user = User.objects.get(pk=kwargs['pk'])
else:
user = request.user
kwargs = {'user': request.user}
return render(request, 'accounts/profile.html', kwargs)
如您所见,您的 view_profile_with_pk
url 模式采用 pk
参数:
url(r'^profile/(?P<pk>\d+)/$', views.ViewProfile.as_view(), name='view_profile_with_pk')
但是在您的 ViewProfile
视图中,您已将 get()
方法配置为:
def get(self, request):
# ...
你可以清楚地注意到get()
正好两个参数,即self
和request
。任何地方都没有 pk
。所以 Django 不知道。
还有。
您可以向 get()
函数添加 *args
和 **kwargs
参数,这将处理您的 url 参数:
def get(self, request, *args, **kwargs):
# ...
然后你可以在函数中自由获取你的 pk
:
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk') # <<<
users = User.objects.all()
object_list = Post.objects.filter(owner=request.user).order_by('-timestamp')
context = {'object_list': object_list, 'users': users}
return render(request, self.template_name, context)
但我不明白为什么你定义了 view_profile
函数,而你可以在 get()
函数中实现它的逻辑:
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
owner = User.objects.get(pk=pk) if pk else request.user # <<<
users = User.objects.all()
object_list = Post.objects.filter(owner=owner).order_by('-timestamp')
# ________________________________^
context = {'object_list': object_list, 'users': users}
return render(request, self.template_name, context)
这将起作用,直到您向视图提供不存在的 pk
。这将导致异常。您可以使用 get_object_or_404()
:
from django.shortcuts import get_object_or_404
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
owner = get_object_or_404(User, pk=pk) if pk else request.user # <<<
users = User.objects.all()
object_list = Post.objects.filter(owner=owner).order_by('-timestamp')
context = {'object_list': object_list, 'users': users}
return render(request, self.template_name, context)
现在您应该有一个功能齐全的视图。
编辑:
正如您刚才所说,视图 return 具有相同的 User
数据。这是因为:
users = User.objects.all()
这一行是没有意义的,因为每次用户向你的视图发送请求,他都会在context
中得到一个users
属性,它正好持有所有的用户在你的数据库中。
一个可能且更有意义的解决方案是将当前用户附加到此 属性:
# ...
context = {'object_list': object_list, 'user': owner}
# _______________________________________^
return render(request, self.template_name, context)
现在视图将 return Post
及其相关的 User
。