Как мне написать запрос Django, где левая часть моего условия WHERE является математическим выражением? - PullRequest
1 голос
/ 08 апреля 2019

Я использую Django, Python 3.7 и PostGres 9.5.У меня есть модель со следующими полями ...

class DomainTrackerStat(models.Model):
    domain = models.CharField(max_length=255)
        ...
    num_negative_articles = models.IntegerField(default=0, null=False)
    num_positive_articles = models.IntegerField(default=0, null=False)

Я хочу написать запрос Django, который говорит, что дают мне все объекты, условия которых соответствуют этому предложению PostGres WHERE

WHERE num_negative_articles / (num_negative_articles + num_positive_articles) > .95

Однако у меня возникают проблемы при написании выражения запроса Django, потому что обычно оно допускает только одно поле, например

DomainTrackerStat.objects.filter(num_negative_articles__gt=.95)

Как мне написать этот более сложный запрос?

Ответы [ 2 ]

2 голосов
/ 08 апреля 2019
Выражения

F () могут использоваться для выполнения арифметических операций (+, -, * и т. Д.) Среди полей модели с целью определения алгебраического поиска / связи между ними.

Объект F () представляет значение поля модели или аннотированного столбца. Это позволяет ссылаться на значения полей модели и выполнять операции с базой данных, используя их без необходимости извлечения их из базы данных в память Python.

data = DomainTrackerStat.objects.annotate(result=F('num_negative_articles') / (F('num_negative_articles') + F('num_positive_articles'))).filter(result__gt=0.95)

Теперь у каждого элемента в данных есть дополнительный столбец с именем «result», который содержит произведение «num_positive_articles» и «num_negative_articles», деленное на «num_negative_articles» каждого элемента соответственно.

Документация для дальнейшей справки

0 голосов
/ 08 апреля 2019

Вы можете аннотировать значение математического выражения в вашем наборе запросов, а затем фильтровать по этому значению аннотации:

DomainTrackerStat.objects.annotate(value=F('num_negative_articles') / (F('num_negative_articles ') + F('num_positive_articles'))).filter(value__gt=0.95)
...