【问题标题】:Django: Query using contains each value in a listDjango:查询使用包含列表中的每个值
【发布时间】:2011-06-17 00:31:19
【问题描述】:

我需要执行一个 django 查询来检查一个字段是否包含列表中的所有值。该列表将具有不同的长度

例子

User.objects.filter(first_name__contains=['x','y','z'])

【问题讨论】:

    标签: django django-models


    【解决方案1】:
    import operator
    from django.db.models import Q
    
    User.objects.filter(reduce(operator.and_, (Q(first_name__contains=x) for x in ['x', 'y', 'z'])))
    

    对于python 3

    from functools import reduce
    

    .

    【讨论】:

    • User.objects.filter(reduce(...)) 他正在做相当于User.objects.filter(Q(first_name__contains='x') & Q(first_name__contains='y') & Q(first_name__contains='z'))
    • 什么是运算符?需要导入吗?
    • @IgnacioVazquez-Abrams 如果您想在 for 循环中使用它,有没有办法将 first_name 替换为每次迭代都会更改的变量(first_namelast_name 等) 同时保留 __contains?现在,我可以看到对多个字段运行它的唯一方法是重复整个函数并硬编码不同的字段名称。
    • 这行代码很珍贵,但是没有任何解释让这个答案很糟糕。
    【解决方案2】:
    import operator
    from django.db.models import Q
    
    q = ['x', 'y', 'z']
    query = reduce(operator.and_, (Q(first_name__contains = item) for item in q))
    result = User.objects.filter(query)
    

    【讨论】:

    • 嘿:)。欢迎来到 SO。介意在你的答案中添加一点肉吗?我们通常喜欢提供比简单的代码转储更多的信息来获得答案,只是为了帮助其他用户更好地了解正在发生的事情:)。谢谢你^^
    • @Patrice 也可以对具有 339K 代表的人对所选答案发表相同的评论。这个答案至少有更多的上下文。 :)
    • 如果使用 Python 3,请使用 import functoolsfunctools.reduce。见this
    【解决方案3】:
    from django.db.models import Q
    User.objects.filter(Q(first_name__contains=x)&Q(first_name__contains=y)&Q(first_name__contains=z))
    

    在 Django 1.8 python 2.7 上为我工作

    doc => https://docs.djangoproject.com/en/1.8/ref/models/querysets/#q-objects

    最新的 => https://docs.djangoproject.com/en/2.1/ref/models/querysets/#q-objects

    【讨论】:

      【解决方案4】:

      接受的解决方案对我不起作用,但确实如此:

      list = ['x', 'y', 'z']
      results = User.objects.filter(first_name__contains=list[0])
      del list[0]
      
      for l in list:
          results = results.filter(first_name__contains=l)
      

      第一个结果变量将存储所有具有 first_name 名称字段值为“x”的对象的列表。

      然后在 for 循环中,在第一个过滤结果中过滤“y”。现在您有了一个 QuerySet,它应该包含一个可以找到 'x' 和 'y' 的项目列表。现在,在您过滤任何包含“z”的项目中。

      这应该适用于任何长度的列表。

      【讨论】:

        【解决方案5】:

        这在 django 2.2、python 3.8 中对我有用,使用 lambda 而不是“运算符”。 关于 lambda 的解释可以在这里找到:https://www.python-course.eu/lambda.php

        from functools import reduce
        from django.db.models import Q
        
        my_list = ['x','y','z']
        User.objects.filter(reduce(lambda x, y: x & y, [Q(first_name__contains= i for i in my_list]))
        

        【讨论】:

          【解决方案6】:

          只是另一种方法。

          qs = User.objects.all()
          for search_term in ('x', 'y', 'z'):
              qs = qs.filter(first_name__contains=search_term)
          

          我不确定它是否更好,但它更具可读性。

          注意:查询集是惰性的,因此此代码进行 1 个 DB 查询。

          【讨论】:

          • 是的,这适用于AND (&) 查询。对于OR (|) 查询,必须使用Q 对象。
          • 我最终使用了同样的方法。我认为这个解决方案实际上比在一行中链接多个Qs 更简洁和可读性更强。它非常适合 op 的问题。
          【解决方案7】:

          这里并不完全适用,但是,如果您有 ManyToManyField 并且您想检查它是否包含特定值,请检查此 https://www.revsys.com/tidbits/tips-using-djangos-manytomanyfield/

          我有一个“产品”和 Django 原生“用户”模型。我的“产品”模型有一个多对多字段users 指向“用户”。然后,我想检查这个类似列表的字段是否包含登录用户。我是通过...users__username_icontains=request.user.username... 完成的,上面的链接帮助我更好地理解什么是多对多字段以及它是如何工作的。

          【讨论】:

            【解决方案8】:
            the_list= []
            
            data_list= ['x', 'y', 'z'] 
            
            for i in data_list:
            
                a = User.objects.filter(first_name__contains=project).values('etc')
            
                the_list+= a
            

            【讨论】:

            • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
            猜你喜欢
            • 1970-01-01
            • 2013-01-19
            • 2015-01-28
            • 2017-02-21
            • 1970-01-01
            • 2023-03-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多