Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.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,我得到了一些具有不同评级字段值的Django模型对象: puzzles_rating = [0, 123, 245, 398, 412, 445, 556, 654, 875, 1000] for rating in puzzles_rating: puzzle = Puzzle(rating=rating) puzzle.save() 现在,对于一个用户_rating=500,我想选择一个与评分最匹配的拼图。在上述情况下,应为等级为445的谜题6 问题

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

puzzles_rating = [0, 123, 245, 398, 412, 445, 556, 654, 875, 1000]
    for rating in puzzles_rating:
        puzzle = Puzzle(rating=rating)
        puzzle.save()
现在,对于一个用户_rating=500,我想选择一个与评分最匹配的拼图。在上述情况下,应为等级为445的谜题6

问题是我不能只做:

puzzle = Puzzle.objects.filter(rating__lte=user_rating).order_by('-rating')[0]
一般来说,我最接近的比赛评分可能高于目标评分


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

您可以获得两个拼图对象,并在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
您可以使用额外的方法:

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

puzzle = Puzzle.objects.extra(select={
    'abs_diff': 'ABS(`rating` - %s)',
}, select_params=(rating,)).order_by('abs_diff').first()
from django.db.models import Func, F

    puzzle = Puzzle.objects.annotate(abs_diff=Func(F('rating') - rating, function='ABS')).order_by('abs_diff').first()