计算Django中__in或__contains查找不匹配的内容

时间:2018-06-29 19:27:41

标签: python django

我正在尝试构建推荐引擎,子任务之一是根据Venues在可用标签列表中匹配的tags来对class Venue(TimeStampedUUIDModel): name = models.CharField(max_length=100, null=False, blank=False) tags = ArrayField( models.PositiveIntegerField( verbose_name=_('tag'), choices=TAGS_CHOICES ), null=True, blank=True ) 进行排名。

这是我的模特:

__contains

我可以在过滤器中进行tag_list查找,以适应列表中某些标签已经存在的场所。但我的动机是也以某种方式知道每个场所都匹配多少个标签,以便为它们分配一些等级。例如,为每个匹配的标签赋予10级。

因此,如果某个场所与tags中的4个标签匹配,则其排名应为4 * 10 = 40。

由于__contains是一个ArrayField,只能包含由正数定义的选择,因此venue_queryset.filter(tags_contains=tag_list).annotate(no_of_tags_matched=...) 查找在过滤器查询中起作用,但是如何注释不匹配的内容?

最终结果可能类似于:

var getUrlParameter = function getUrlParameter(sParam) {
    var sPageURL = decodeURIComponent(window.location.search.substring(1)),
        sURLVariables = sPageURL.split('&'),
        sParameterName,
        i;

    for (i = 0; i < sURLVariables.length; i++) {
        sParameterName = sURLVariables[i].split('=');

        if (sParameterName[0] === sParam) {
            return sParameterName[1] === undefined ? true : sParameterName[1];
        }
    }
};

var keyword = getUrlParameter('keyword ');

请让我知道是否需要更多信息。

1 个答案:

答案 0 :(得分:0)

因此,我使用Case解决了此问题,该条件映射到使用When条件的SQL情况。

user_interested_in_tag_list是用户感兴趣的标签列表,其逻辑是将每个场所排在第一个。与该列表匹配的标签。

from django.db.models import (
    Case, ExpressionWrapper, IntegerField, Q, Value, When
)
from functools import reduce


def calculate_user_interest_rank(venue_queryset, user_interested_in_tag_list):
    if user_interested_in_tag_list:
        # Add rank of 10 for each matched tag in the venue
        user_interest_match_query = map(
            lambda x: Case(
                When(Q(tags__contains=[x, ]), then=Value(10)), default=Value(0)
            ), user_interested_in_tag_list
        )
        user_interested_tags_matches = reduce(
            lambda x, y: x + y, user_interest_match_query
        )
        venue_queryset = venue_queryset.annotate(
            user_interest_score=ExpressionWrapper(
                user_interested_tags_matches,
                output_field=IntegerField()
            )
        )
    else:
        venue_queryset = venue_queryset.annotate(
            user_interest_score=ExpressionWrapper(
                Value(0),
                output_field=IntegerField()
            )
        )

user_interest_match_query将是When子句的列表,其中包括{{1}中每个匹配标签的Value10user_interest_match_query否则为Value

然后0user_interested_tags_matches子句所有结果的总和,该子句给出When中注释的每个场所的实际得分。

我希望这对某人有帮助:)如果您需要更多详细信息,请告诉我。