【问题标题】:Applying custom mixin and lookups with Q objects behavior使用 Q 对象行为应用自定义 mixin 和查找
【发布时间】:2018-06-10 06:00:04
【问题描述】:

我有以下 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 对象查找用户:

当我们通过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 的用户数据。

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

我稍微改变了基于类的视图 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)

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

但我现在的 Q 查找查询不起作用

为什么UserProfileDataMixin 的原因在我覆盖get 方法时不适用于我的基于类的视图SearchView 但如果当我覆盖get_queryset 方法时,但这消除了我的自定义查找的效果q对象查询?

什么时候应该使用get,什么时候应该使用get_queryset

this answer question 中解释一下这个主题,我认为使用get_queryset 是合适的,但是,为什么我的查询与使用get 方法时的方式不同?为什么使用 get 方法我的UserProfileDataMixin 没有被继承?

【问题讨论】:

    标签: django django-queryset mixins


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

    【讨论】:

      猜你喜欢
      • 2017-09-16
      • 2015-05-13
      • 2013-02-27
      • 1970-01-01
      • 2020-09-16
      • 1970-01-01
      • 2021-09-15
      • 2016-11-20
      • 2012-04-18
      相关资源
      最近更新 更多