过滤后如何保留分配给queryset对象的属性?备择方案?

时间:2019-04-15 00:28:27

标签: python django python-3.x django-models django-queryset

也许这是一个坚定的答案,所以我将解释为什么要这么做。

我有一个产品的模型。我必须给他们每个分配一些库存

因此,我在Products模型上具有功能,该功能可以计算很多必要的东西,例如库存,并返回QuerySe

由于我的数据库模型有点“复杂”,因此在这种情况下我无法使用注释。因此,我决定手动执行此数据库查询,然后在查询中分配每种产品手动设置库存属性。像这样:

for product in queryset_products:
    product.stock = some_stock_calc...

当我想使用此查询集产品的过滤器时,问题就来了。 在执行类似这样的操作之后:

queryset_products = queryset_products.filter(...)

库存属性丢失

有解决方案吗?

3 个答案:

答案 0 :(得分:0)

由于您无法使用annotate(),因此,如果您可以添加单独的列以将stock存储在Product表中,则可以对任何{时间。 也许有一个filter任务,它为每个celery进行所有计算并保存到新列中。

否则,如果没有Product,则无法在查询集中拥有annotate属性。

答案 1 :(得分:0)

在查询集上枚举之前,对查询集的所有操作(例如.filter())都是符号操作。然后,将编译并执行一个SQL查询。计算未经过滤的大型查询集上的存量,然后再次运行经过过滤的存量是无效的。您可以将过滤器拆分为与附加到查询集的与库存无关的条件,然后将与您在计算库存的同一Python循环中评估的库存相关的条件过滤。

result = []   
for product in queryset_products.filter(**simple filters):
    product.stock = some_stock_calc...
    if product.stock > 0 or not required_on_stock:
        result append(product)

第一个简单过滤器非常有用,它可以缓存可能存有有效产品的缓存字段。

也许库存计算并不复杂,例如午夜存货,加上午夜以来的存货操作总和。然后,可用Subquery在注释中计算当前库存并一起过滤。它将被编译为一个SQL,并带有与相关模型的连接的主查询和一个相对简单的股票子查询。 (那是另一个问题。)

答案 2 :(得分:0)

可以解决不同的问题,您可以运行一个循环

    0    because they are nice and funny 
    1    many people love cats because 
    2    hamsters are very small and furry creatures
    3    i got a dog because i know because they are nice and funny
    4    birds are funny when they dance to music, they bop up and down
    Name: Summary, dtype: object

基本上,您需要从数据库中获取所有记录,因为查询是惰性的,它将丢失,因为除非重新存储/存储结果,否则它将被重新评估。