Django,具有按用户full_name筛选的Q对象

时间:2019-04-02 01:17:07

标签: django python-3.x django-views django-queryset

我有一个简单的搜索框,可以按标题,名字,姓氏搜索帖子(过滤帖子),但是无论我怎么努力,我都无法按用户full_name进行搜索

我的模型中有

User.full_name = property(lambda u: u"%s %s" % (u.first_name, u.last_name))

在我的终端机Django Shell中,我得到了以下结果

>>> user.first_name
'Blake'
>>> user.last_name
'Lively'
>>> user.full_name
'Blake Lively'

现在,当我尝试使用用户全名搜索时,出现以下错误

  

相关字段的查询无效:全名

Q(user__full_name__icontains=query)

以下是我的观点

class QList(SelectRelatedMixin, ListView):
    model = Question
    select_related = ('user', 'group')
    template_name = 'questions/all_questions.html'
    context_object_name = 'all_questions'
    paginate_by = 5

    def get_queryset(self):
        queryset = super(QList, self).get_queryset().order_by('-created_at')
        query = self.request.GET.get('q')
        if query:
            queryset = queryset.filter(
                Q(title__icontains=query) | #This works
                Q(user__username__iexact=query) | #This works
                Q(user__first_name__iexact=query) | #This works
                Q(user__last_name__iexact=query) | #This works
                Q(user__full_name__icontains=query) #This Fails what am I doing worng

                )
        return queryset
  

尝试过

class QList(SelectRelatedMixin, ListView):
    model = Question
    select_related = ('user', 'group')
    template_name = 'questions/all_questions.html'
    context_object_name = 'all_questions'
    paginate_by = 5

    def get_queryset(self):
        queryset = super(QList, self).get_queryset().order_by('-created_at')
        query = self.request.GET.get('q')

        if ' ' in query:
            query = query.split()
            queryset = queryset.filter(
                chain(User.objects.filter(first_name__icontains=query[0], last_name__icontains=query[1]),
                      User.objects.filter(first_name__icontains=query[1], last_name__icontains=query[0])))

            return queryset
        else:
            queryset = queryset.filter(
                Q(title__icontains=query) |
                Q(user__username__iexact=query) |
                Q(user__first_name__iexact=query) |
                Q(user__last_name__iexact=query)

                )
        return queryset

遇到错误

  

“ NoneType”类型的参数不可迭代

if ' ' in query:

2 个答案:

答案 0 :(得分:3)

不能将filter()与此类属性一起使用,为了使过滤器正常工作,它必须是模型字段。

检查this线程以使用管理器或注释查看一些可能的解决方法。

编辑新错误:

在没有query = self.request.GET.get('q')的情况下,您的None返回q,并且您无法在None中检查任何内容。将该行更改为query = self.request.GET.get('q', ''),因此,如果没有q,则默认为空字符串。

答案 1 :(得分:1)

感谢@gdef_下面的代码完成了工作

class QList(SelectRelatedMixin, ListView):
    model = Question
    select_related = ('user', 'group')
    template_name = 'questions/all_questions.html'
    context_object_name = 'all_questions'
    paginate_by = 5

    def get_queryset(self):
        queryset = super(QList, self).get_queryset().order_by('-created_at')
        query = self.request.GET.get('q', None)

        if query:
            queryset = queryset.annotate(
                full_name=Concat(
                    'user__first_name',
                    Value(' '),
                    'user__last_name',
                    output_field=CharField()
                )
            ).filter(
                Q(full_name__icontains=query) |
                Q(title__icontains=query) |
                Q(user__username__iexact=query) |
                Q(user__first_name__iexact=query) |
                Q(user__last_name__iexact=query)

                )
        return queryset