使用 Q objects 行为应用自定义混合和查找

Applying custom mixin and lookups with Q objects behavior

我有以下 mixin,我想在其中检索用户模型数据以将这些数据放置在我正在开发的基于不同类的视图中:

class UserProfileDataMixin(object):
    def get_context_data(self, **kwargs):
        context = super(UserProfileDataMixin, self).get_context_data(**kwargs)
        user = self.request.user
        #context['userprofile'] = user.profile
        if user.is_authenticated():
            context['userprofile'] = user.profile
        return context

然后,我有以下搜索视图,其中我根据以下条件使用 Q objects:

查找用户

当我们按 usernamefull_name 字段搜索时

class SearchView(UserProfileDataMixin, ListView):
    template_name = 'search.html'
    def get(self, request, *args, **kwargs):
        query = request.GET.get("q")
        qs = None
        if query:
            qs = User.objects.filter(
                Q(username__icontains=query) |
                Q(full_name__icontains=query)
            )
        context = {"users": qs}

        return render(request, "search.html", context)

当我从 UserProfileDataMixin 继承时,这个 mixin 使我有可能将 userprofile 上下文变量传递给我的 search.html 模板,该模板继承自 layout.html模板,我在其中执行以下验证:

search.html模板

{% extends "layout.html" %}

layout.html模板

{% if userprofile %}
    I put the data of user by example:
    avatar, username, full_name, and menu options to my app.   
{% endif %}

到这里为止,一切正常,但是我基于 class 的视图 SearchView 不应用 UserProfileDataMixin 因为,我无法在我的模板上获取用户数据,这些数据来自 layout.html.

当我得到搜索用户模板时,我得到:

我稍微更改了基于 class 的视图 SearchView 覆盖 get_queryset 方法而不是 get 方法 a

class SearchView(UserProfileDataMixin, ListView):
        template_name = 'search.html'
    def get_queryset(self):
        query = self.request.GET.get("q")
        qs = None
        if query:
            qs = User.objects.filter(
                Q(username__icontains=query) |
                Q(full_name__icontains=query)
            )
        context = {"users": qs}
        return render(self.request, "search.html", context)

我基于 class 的视图 SearchView 应用 UserProfileDataMixin 因为我可以从我的模板上的 layout.html 获取用户数据。现在出现我的 header 菜单,它是由 UserProfileDataMixin

带来的

但我现在的不便之处是我的Q查找查询不起作用

为什么 UserProfileDataMixin 的原因不适用于我基于 class 的视图 SearchView,当我覆盖 get 方法时,但如果当我覆盖 [=26] =] 方法,但这删除了我的自定义查找 q object 查询的效果?

什么时候用get,什么时候用get_queryset

中解释了主题,我认为使用get_queryset是合适的,但是,为什么我的查询执行方式与我使用[=27时的方式不同=] 方法?为什么使用get方法我的UserProfileDataMixin不被继承?

get() 的基本实现会为您调用 get_context_data()。但是,因为您已经用自己的实现覆盖了 get(),所以您需要自己调用 get_context_data()

class SearchView(UserProfileDataMixin, ListView):
    template_name = 'search.html'

    def get(self, request, *args, **kwargs):
        query = request.GET.get("q")
        qs = None
        if query:
            qs = User.objects.filter(
                Q(username__icontains=query) |
                Q(full_name__icontains=query)
            )

        # Get the context data from the base class (mixin) and update it
        context = super(SearchView, self).get_context_data()
        context["users"] = qs

        return render(request, "search.html", context)

但是,更好的解决方案可能是完全不覆盖 get(),并在您的 SearchView 中实施特定视图 get_context_data()。例如

class SearchView(UserProfileDataMixin, ListView):
    template_name = 'search.html'

    def get_context_data(self, **kwargs):
        query = self.request.GET.get("q")
        qs = None
        if query:
            qs = User.objects.filter(
                Q(username__icontains=query) |
                Q(full_name__icontains=query)
            )
        context = super(SearchView, self).get_context_data(**kwargs)
        context["users"] = qs
        return context

最后,您的 get_queryset() 实现没有做正确的事情,因为该方法旨在 return 一个 QuerySet 对象,而在您的情况下它正在呈现一个模板。