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'},
]

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

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

,但列表中的对象数量可能很大。如果对象存在,有什么合适的方法可以立刻得到它们吗?或者至少以最小的db命中量获得它们。

提前感谢!

您可以像这样使用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)

您可以使用字段查找"in"

# get all the vendor codes in a list
vendor_code_list = []
for v in values:
vendor_code_list.append(v['vendor_code'])
# query all the fabrics
fabrics = Fabric.objects.filter(vendor_code__in=vendor_code_list)

如果你想匹配精确的值,并且你确定你的项键是有效的字段名,你可以:

for item in values:
fabric = Fabric.objects.filter(**item)

否则,如果你想检查你的项目是否包含在现有的项目中,你可以:

for item in values:
item_in = {'{}__in'.format(key):val for key, val in item.items()}
fabric = Fabric.objects.filter(**item_in)

相关内容

  • 没有找到相关文章

最新更新