首页 > 解决方案 > Django,通过多个值获取对象

问题描述

有一个型号

class Fabric(models.Model):
    vendor_code = models.CharField(max_length=50)
    color = models.CharField(max_length=50)
    lot = models.CharField(max_length=50)

我有一个对象列表

values = [
   {'vendor_code': '123', 'color': 'aodfe', 'lot': 'some lot 1'}, 
   {'vendor_code': '456', 'color': 'adfae', 'lot': 'some lot 2'},
   {'vendor_code': '789', 'color': 'dvade', 'lot': 'some lot 3'},
]

dict 对象中没有 id。如何让对象检查字段值列表(每个对象同时检查所有 3 个值)?我知道我可以在循环中一一查询:

for item in values:
    fabric = Fabric.objects.filter(vendor_code=item['vendor_code'], color=item['color'], lot=item['lot'])

但列表中的对象数量可能很大。如果对象存在,是否有任何适当的方法可以立即获取对象?或者至少以最少的分贝命中率获得它们。

提前致谢!

标签: djangodjango-querysetmultivalue

解决方案


您可以像这样使用in ( __in) 过滤器:

fabrics = Fabric.objects.filter(
    vendor_code__in=[value['vendor_code'] for value in values],
    color__in=[value['color'] for value in values],
    lot__in=[value['lot'] for value in values],
    )

然而,这将迭代values列表 3 次,只迭代一次,使用如下内容:

vendor_codes = []
colors = []
lots = []
for value in values:
    vendor_codes.append(value['vendor_code'])
    colors.append(value['color'])
    lots.append(value['lot'])


fabrics = Fabric.objects.filter(
    vendor_code__in=vendor_codes,
    color__in=colors,
    lot__in=lots,
    )

要同时根据所有三个值进行过滤,您必须像这样使用Q 对象

q_objects = []
for value in values:
    q_objects.append(Q(
        vendor_code=value['vendor_code'],
        color=value['color'],
        lot=value['lot']
        )
    )
final_q_object = Q()
for q_object in q_objects:
    final_q_object.add(q_object, Q.OR)


fabrics = Fabric.objects.filter(final_q_object)

它的要点是得到这个查询:

Q(Q(a=i, b=j, c=k)) | Q(Q(a=l, b=m, c=n) | ...)

经过一番优化后的最终答案:

final_query = Q()
for item in values:
    final_query.add(
        Q(
            vendor_code=value['vendor_code'],
            color=value['color'],
            lot=value['lot']
        ),
        Q.OR
    )
fabrics = Fabric.objects.filter(final_query)

推荐阅读