在我之前提出的一个问题:如何在同一个基于类的视图下拥有两个单独的查询集。由于语法错误,最初的问题很简单但在修复之后我得到:get() got an unexpected keyword argument 'pk'
我认为这是我写我的观点的一个问题。
编辑:澄清问题:如何使用两个查询集,一个调用用户的pk信息,另一个调用用户列出同一类的用户列表。
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)
# 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>
答案 0 :(得分:2)
如您所见,您的view_profile_with_pk
网址格式需要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不知道它。
然而
您可以在*args
函数中添加**kwargs
和get()
个参数,这些参数将处理您的网址参数:
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)
现在你应该有一个功能齐全的视图。
修改强>
正如您刚才所说,该视图返回相同的User
数据。这是因为:
users = User.objects.all()
这一行毫无意义,因为每次用户向您的视图发送请求时,他都会在users
中获得context
属性,该属性只包含您数据库中的所有用户。
一种可能且更有意义的解决方案是将当前用户附加到此属性:
# ...
context = {'object_list': object_list, 'user': owner}
# _______________________________________^
return render(request, self.template_name, context)
现在该视图将返回Post
及其相关的User
。
答案 1 :(得分:1)
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)