Django F () - избегайте автоматических c скобок - PullRequest
1 голос
/ 26 января 2020

Я использую F () для расчетов между столбцами таблицы базы данных. Я строю формулу, используя al oop. Я добавляю каждый F (столбец) к формуле в каждом цикле l oop:

1. cycle: formula = F(col1)
2. cycle: formula += F(col2)
3. cycle: formula *= F(col3)

Затем я использую формулу в запросе, подобном этому:

test = Model.objects.all().values('id').annotate(calc=formula)

Когда я делаю print (test.query), я получаю:

SELECT id, ((col1+col2)*col3) as calc FROM table;

Правильный математический порядок будет:

(col1+(col2*col3))

Как сохранить прецедент в этом случае?

1 Ответ

2 голосов
/ 26 января 2020

Если вы сделаете что-то вроде этого:

Model.objects.all().values(id).anotate(calc=F(column_a)+F(column_b)*F(column_c))

Вы получите запрос типа:

SELECT id, ((column_a+column_b)*column_c) as calc FROM table;

Ваше предположение неверно . Вы можете проверить запрос с помощью:

<b>print(</b>Model.objects.values('id').anotate(calc=F(column_a)+F(column_b)*F(column_c))<b>.query)</b>

, и вы увидите, что он создает запрос, который выглядит следующим образом:

SELECT id, (column_a + (column_b * column_c))
FROM model

Это логично, поскольку объект может не изменить приоритет операторов. Они определяются грамматикой Python. Как видите, грамматика Python для двоичная арифметика c operator [Python -doc] указывает, что * имеет более высокий приоритет, чем +:

...