Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django加权查询(带注释的值)_Python_Django_Django Queryset - Fatal编程技术网

Python Django加权查询(带注释的值)

Python Django加权查询(带注释的值),python,django,django-queryset,Python,Django,Django Queryset,我试图创建一个查询,并根据自定义的权重计算对其进行排序 我需要一些帮助,因为我找到的解决方案确实有效,但性能不是我想要的 我拥有的是一个媒体对象。它有相关的评论,喜欢和命令 以下查询目前有效,但却是一团乱麻: products = (Media.objects .select_related( 'image', 'currency', 'user', 'user__image'

我试图创建一个查询,并根据自定义的权重计算对其进行排序

我需要一些帮助,因为我找到的解决方案确实有效,但性能不是我想要的

我拥有的是一个媒体对象。它有相关的评论,喜欢和命令

以下查询目前有效,但却是一团乱麻:

    products = (Media.objects
        .select_related(
            'image',
            'currency',
            'user',
            'user__image',
        )
        .prefetch_related('category', 'tags')
        .exclude(is_deleted=1)
        .filter(Q(category__category__in=categories) | Q(tags__tag__title=query))
        .annotate(order_count = Count('orders', distinct=True))
        .annotate(comment_count = Count('comments', distinct=True))
        .annotate(like_count = Count('likes', distinct=True))
        .annotate(weight = Count(0))
        .distinct())
    
    for m in products.iterator():
        initial_weight  = int(m.order_count)*40 + int(m.comment_count)*4 + int(m.like_count)*4 + int(m.clicks)
        m.weight        = float(float(initial_weight) - float(m.views/50))
正如你所看到的,我分别注释了我将要使用的所有参数,然后对queryset中的每一项进行了一次愚蠢的、充满算术运算的迭代,这是非常次优的

我尝试做的一件事是:

    products = (Media.objects
        .select_related(
            'image',
            'currency',
            'user',
            'user__image',
        )
        .prefetch_related('category', 'tags')
        .exclude(is_deleted=1)
        .filter(Q(category__category__in=categories) | Q(tags__tag__title=query))
        .annotate(weight = Count('orders', distinct=True) * 40 + Count('comments', distinct=True) * 4 + Count('likes', distinct=True) - F('views')/50 + F('clicks')))
但是注释中的类似操作是不可能的(尝试了一些有Sum()和没有Sum()的变体)-Django总是抱怨注释值的类型不同

顺便说一下,我们在这个项目中使用了django 1.8


是否有一个很好的单一查询方法来获取所需的排序权重?

首先,您需要确保除法将产生浮点值(无舍入)。您需要类似以下内容():

因此,查询将如下所示:

products = (Media.objects
    .exclude(is_deleted=1)
    .filter(Q(category__category__in=categories) | Q(tags__tag__title=query))
    .annotate(order_count = Count('orders', distinct=True))
    .annotate(comment_count = Count('comments', distinct=True))
    .annotate(like_count = Count('likes', distinct=True))
    .annotate(weight = Count(0))
    .annotate(
        initial_weight=ExpressionWrapper(
            F('order_count') * 40 + F('comment_count') * 4 +
            F('like_count') * 4 + F('clicks'),
            output_field=FloatField()
        )
     )
    .annotate(
        views_divided=ExpressionWrapper((F('views') / Decimal(50.0), 
                                        output_field=FloatField()))
     )
    .annotate(weight=F('initial_weight') - F('views_divided'))
    .distinct())
看起来很难看,但应该有用(我想)


另一方面-如果您只需要计算
权重
,实际上不必使用
预取相关的
选择真实的
,django将自行处理这些内容(不过,这只是我的猜测-如果您在代码中稍后实际使用这些外键,那么它是合理的).

非常感谢。是的,它有点难看,但ExpressionWrapper做到了!只有一张纸条(有点奇怪)需要将初始重量和ExpressionWrapper包装在内!我将在最终解决方案中进行编辑。PS我需要用于其他目的的select_,但事实上它不是必需的,这也是有价值的!非常感谢。很高兴它有帮助。我还将更新答案,以防有人发现您的问题。
products = (Media.objects
    .exclude(is_deleted=1)
    .filter(Q(category__category__in=categories) | Q(tags__tag__title=query))
    .annotate(order_count = Count('orders', distinct=True))
    .annotate(comment_count = Count('comments', distinct=True))
    .annotate(like_count = Count('likes', distinct=True))
    .annotate(weight = Count(0))
    .annotate(
        initial_weight=ExpressionWrapper(
            F('order_count') * 40 + F('comment_count') * 4 +
            F('like_count') * 4 + F('clicks'),
            output_field=FloatField()
        )
     )
    .annotate(
        views_divided=ExpressionWrapper((F('views') / Decimal(50.0), 
                                        output_field=FloatField()))
     )
    .annotate(weight=F('initial_weight') - F('views_divided'))
    .distinct())