如何在同一个基于 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() 正好两个参数,即selfrequest。任何地方都没有 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