How to implement a QuerySet filter on Cartesian product/List of lists?

问题描述 投票:0回答:2

我想根据嵌套列表的值在 Django 中实现查询集过滤,例如

titles = [ ['nike', '38', 'blue'], 
          ['nike', '38', 'grey'],
          ['adidas', '38', 'blue'], 
          ['adidas', '38', 'grey'],
          ['salmon', '38', 'blue'], 
          ['salmon', '38', 'grey'] ]

查询集是:

queryset = Product.objects.all()

你有什么建议动态地做下面的事情:

# | mark means OR
queryset.filter(attribute__title='nike').filter(attribute__title='38').filter(attribute__title='blue') |
queryset.filter(attribute__title='nike').filter(attribute__title='38').filter(attribute__title='grey') |
queryset.filter(attribute__title='adidas').filter(attribute__title='38').filter(attribute__title='blue') |
...
queryset.filter(attribute__title='salmon').filter(attribute__title='38').filter(attribute__title='grey')

如果您对数据库模式感兴趣:

django list filter django-queryset
2个回答
0
投票

从您发布的数据库模式中不清楚您的 ORM 模型是什么样子,但为了给您一个想法,这就是您使用

Q
对象实现动态过滤器的方式:

from django.db.models import Q

titles = [['nike', '38', 'blue'],
          ['nike', '38', 'grey'],
          ['adidas', '38', 'blue'],
          ['adidas', '38', 'grey'],
          ['salmon', '38', 'blue'],
          ['salmon', '38', 'grey']]

colums = ['brand', 'size', 'color']

query = Q()
for title in titles:
    subquery = Q()
    for column_name, value in zip(colums, title):
        subquery &= Q(**{column_name: value})
    query |= subquery

queryset = Product.objects.filter(Q)

澄清一下,

query
对象的值最终会类似于下面这样:

(OR: 
    (AND: ('brand', 'nike'), ('size', '38'), ('color', 'blue')), 
    (AND: ('brand', 'nike'), ('size', '38'), ('color', 'grey')), 
    (AND: ('brand', 'adidas'), ('size', '38'), ('color', 'blue')),
    ...
)

您可以调整

columns
列表中的值以适合您的模式。


0
投票

可以通过对子列表中的每个属性重复调用

filter
方法,为每个子列表动态生成查询集,然后使用OR运算符创建所有查询集的并集:

from functools import reduce
from operator import or_

queries = []
for attributes in titles:
    query = queryset
    for attribute in attributes:
        query = query.filter(attribute__title=attribute)
    queries.append(query)
query = reduce(or_, queries)
© www.soinside.com 2019 - 2024. All rights reserved.