【问题标题】:Django filtering in exclusivelyDjango 专门过滤
【发布时间】:2013-11-30 07:05:36
【问题描述】:

如果查询在列表中,以下是 Django 过滤:

options = [1,2,3]
result = Example.objects.filter('something__property__in'=options)

所以这里somethingForeignKeyExample 的关系(具有多个关系)

我希望result 是所有something 为1 AND 2 AND 3 的Examples。上面的示例代码将是1 OR 2 OR 3。这将是排他性的!

示例

以下内容将result

examples = Example.objects.all()
things = examples[0].something.all()
for thing in things: print thing.property
#1
#2
#4
#7

以下内容位于result

examples = Example.objects.all()
things = examples[0].something.all()
for thing in things: print thing.property
#1
#2
#8
#9
#3

第二个示例的原因是 options 中的所有内容,其中第一个示例有 1 和 2,但没有 3!

在 Django 中是否有一种简单的方法可以做到这一点?

我唯一能想到的就是使用上面给出的示例进行过滤,将所有properties 放入一个列表中。并将列表与以下python函数中的options进行比较:

def exclusive_in(list1,list2):
    count = 0
    for i in list1:
        if i in list2:
            count += 1
    if count == len(list2):
        return True
    else:
        return False

我觉得 Django 可以在它对数据库的查询中做到这一点,这样会更有效率。有什么想法吗?

注意:

这必须适用于options 中任意数量的项目,它可以是大于 2 的任何数字,甚至是 10 或 100(虽然不太可能是 100,但仍有可能)

还要注意options 将由字符串填充

【问题讨论】:

    标签: python sql django


    【解决方案1】:

    我知道的唯一方法是使用extra 方法传入查询一些自定义条件。

    Django won't allow youtables 参数传递这个条件,所以它必须在where 中。请参阅以下带有django.contrib.auth models 的示例(示例中的管理员组拥有所有权限):

    >>> from django.contrib.auth import models
    >>> permissions_id = [1,2]
    >>> where = """(select count(1)
    ...               from auth_group_permissions gp
    ...              where gp.permission_id in ({})
    ...                and gp.group_id = auth_group.id) = {}"""    
    >>> where = where.format(','.join(map(str, permissions_id)), 
    ...                      str(len(permissions_id )))
    >>> models.Group.objects.extra(where=[where]).all()
    [<Group: Admin>]
    >>> print models.Group.objects.extra(where=[where]).all().query
    SELECT `auth_group`.`id`, `auth_group`.`name` 
      FROM `auth_group` WHERE (select count(1)
                          from auth_group_permissions gp
                         where gp.permission_id in (1,2)
                           and gp.group_id = auth_group.id) = 2
    

    【讨论】:

    • 我不能 100% 确定这是否适用于 options 列表中的任意数量的项目。你能给我一个示例输出吗?
    • @Ryan,独家是什么意思?这个 orm 请求,如 SQL(底部)所示,返回所有具有 id 1 和 2 的相关权限的组。如果不会忘记,稍后将添加一些 db 数据转储以进行解释。由于joinlen 的使用,您可以将结果更改为任何pemissions_id 列表。 棘手但可实现的地方在于,在生成任意模型时,您必须推断出正确的表和字段名称。
    • 你理解我的排他的意思:它必须包含options 或你的情况下为permissions_id 的所有项目。我的问题是,正如您刚才所指出的,这只有在您事先确切知道列表是什么的情况下才有效。我需要它用于任意数量的选项,其中没有一个选项是已知的。这是一个 API。
    • @RyanSaxe 我再次感到困惑,因为您知道示例中的选项列表(list2)。 list2 与我的代码中的permissions_id 具有相同的含义,一旦你知道它们,格式化并运行extra 以获得结果。
    • 我知道,这正是我的意思,我不会知道他们,因为这是一个 API!人们需要能够通过 API 使用这种排他性搜索,所以我不能硬编码 where,因为 list2 中的项目以及有多少项目都是未知的!
    猜你喜欢
    • 1970-01-01
    • 2022-07-04
    • 1970-01-01
    • 1970-01-01
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    • 2015-08-18
    相关资源
    最近更新 更多