应用自定义mixin和查找Q对象行为

时间:2018-06-10 06:00:05

标签: django django-queryset mixins

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

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对象的以下标准查找用户:

当我们按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 %}

在此之前,一切正常,但我的基于班级的观看次数SearchView不适用UserProfileDataMixin,因为我无法在我的模板上获取来自layout.html的用户数据。< / p>

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

enter image description here

我略微更改了基于班级的视图SearchView,而不是get_queryset方法,而不是get方法

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)

我的基于班级的视图SearchView会应用UserProfileDataMixin,因为我可以在我的模板上从layout.html获取用户数据。现在出现我的顶级标题菜单,由UserProfileDataMixin

带来

enter image description here

但是我现在不方便我的Q查询查询不起作用

当我覆盖UserProfileDataMixin方法但是当我覆盖SearchView方法时,为什么get的原因未应用于基于类的视图get_queryset,但是删除我自定义查找q对象查询的效果?

我应该何时使用get,何时使用get_queryset

this answer question解释主题,我认为使用get_queryset是合适的,但是,为什么我的查询的执行方式与我使用get的方式相同方法?为什么使用get方法我的UserProfileDataMixin不会被继承?

1 个答案:

答案 0 :(得分:1)

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(),并在get_context_data()中实施特定于视图的SearchView。 e.g。

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()实现没有做正确的事情,因为该方法旨在返回QuerySet对象,而在您的情况下,它正在呈现模板。