Есть ли способ отфильтровать набор запросов в Django на основе двух столбцов? например | х-10 | > 5 и | y-5 | > 5 - PullRequest
0 голосов
/ 13 июня 2019

В начале я не очень хорош в английском. я прошу прощения. Я хочу отфильтровать результаты по абсолютному значению из двух столбцов. Я пробовал так много способов, но не смог найти никакого полезного решения.

# This is my model
class Driver(models.Model):
    account = GenericRelation(Account, related_query_name='drivers')
    rating = models.FloatField()
    x = models.FloatField()
    y = models.FloatField()
    active = models.BooleanField(default=False)

# I want filter something like this But :(
drivers = Driver.objects.filter(abs(Driver.y - 5) > 5 and abs(Driver.x - 10) > 5)

1 Ответ

3 голосов
/ 13 июня 2019

Да, мы можем сначала аннотировать набор запросов, а затем фильтровать аннотации. Поскольку мы можем использовать выражение Abs(..) [Django-doc] :

from django.db.models import <b>F</b>
from django.db.models.functions import <b>Abs</b>

drivers = Driver.objects.annotate(
    <b>abs_xy=Abs(F('x') - F('y'))</b>
).filter(abs_xy__gt=5)

Здесь мы, таким образом, фильтруем Driver объекты, которые имеют | x-y |> 5 .

Мы также можем добавить несколько аннотаций, например:

from django.db.models import <b>F</b>
from django.db.models.functions import <b>Abs</b>

drivers = Driver.objects.annotate(
    <b>abs_x10=Abs(F('x') - 10)</b>,
    <b>abs_y5=Abs(F('y') - 5)</b>
).filter(abs_x10__gt=5, abs_y5__gt=5)

Это даст Driver с при | x-10 |> 5 и | y-5 |> 5 .

Если версия Django ниже , вы можете реализовать это, как в Django-библиотеке [GitHub] :

from django.db.models.lookups import Transform

# ...

class Abs(Transform):
    function = 'ABS'
    lookup_name = 'abs'
...