【问题标题】:Django model query for the closest integer matchDjango 模型查询最接近的整数匹配
【发布时间】:2015-06-01 01:14:19
【问题描述】:

我得到了一些具有不同评级字段值的 Django 模型对象:

puzzles_rating = [0, 123, 245, 398, 412, 445, 556, 654, 875, 1000]
    for rating in puzzles_rating:
        puzzle = Puzzle(rating=rating)
        puzzle.save()

现在,对于user_rating = 500,我想选择评级匹配最接近的拼图。在上面的例子中,它应该是第 6 个谜题,评分为 445。

问题是我不能这样做:

puzzle = Puzzle.objects.filter(rating__lte=user_rating).order_by('-rating')[0]

一般来说,我最接近的匹配评分可能高于目标评分。

有没有一种方便的方法可以从两个方向查询最接近的匹配项?

【问题讨论】:

    标签: python django django-queryset


    【解决方案1】:

    您可以使用extra 方法:

    puzzle = Puzzle.objects.extra(select={
        'abs_diff': 'ABS(`rating` - %s)',
    }, select_params=(rating,)).order_by('abs_diff').first()
    

    从 Django 1.8 开始,您不需要编写原始 SQL,您可以使用Func

    from django.db.models import Func, F
    
        puzzle = Puzzle.objects.annotate(abs_diff=Func(F('rating') - rating, function='ABS')).order_by('abs_diff').first()
    

    【讨论】:

      【解决方案2】:

      您可以同时获取 Puzzle 对象并在更接近的 Python 中进行比较:

      # Note, be sure to check that puzzle_lower and puzzle_higher are not None
      puzzle_lower = Puzzle.objects.filter(rating__lte=user_rating).order_by('-rating').first()
      puzzle_higher = Puzzle.objects.filter(rating__gte=user_rating).order_by('rating').first()
      
      # Note that in a tie, this chooses the lower rated puzzle
      if (puzzle_higher.rating - user_rating) < abs(puzzle_lower.rating - user_rating):
          puzzle = puzzle_higher
      else:
          puzzle = puzzle_lower
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-24
        • 1970-01-01
        • 2011-03-01
        相关资源
        最近更新 更多