Использование связанных моделей с условным выражением

#python-3.x #django #django-rest-framework #django-2.2 #django-annotate

#python-3.x #django #django-rest-framework #django-2.2 #django-аннотировать

Вопрос:

Цель: использовать связанный атрибут модели в качестве фильтра внутри условного выражения для аннотации.

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

Однако я не могу этого сделать.

Пусть у нас будут модели A, B и C.

 class ModelA(models.Model):
    name=models.Charfield()
    reference=models.ForeignKey('app.ModelB')

class ModelB(models.Model):
    name=models.Charfield()

class ModelC(models.Model):
    name=models.Charfield()
    reference=models.ForeignKey('app.ModelB', related_name='some_reference')
    bool_field=models.BooleanField()
  

И это то, что я хотел бы сделать:

 ModelA.objects.all().annotate(some_field=When(Q(reference__some_reference__bool_field=True), 
                                                then=F('reference_some_reference_name')))
  

Это должно сработать, поскольку оно интерпретируется python, но я получаю некоторую синтаксическую ошибку от MySQL.
Что я делаю не так? Возможно ли это вообще?

Это то, что я получаю:

 django.db.utils.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHEN `ParametrosPreciosProveedor`.`already_iva` = 1 THEN `ParametrosPreciosProve' at line 1")

  

‘ParametrosPreciosProveedor’ — это ModelC в этом примере, а ‘already_iva’ — это bool_field .

Ответ №1:

Я бы попробовал удалить When и then части аннотации. Объекты Q выполняют это автоматически — вы не определяете эти термины в Python.

 ModelA.objects.all().annotate(some_field=Q(reference__some_reference__bool_field=True), 
                          F('reference_some_reference_name')))
  

Ознакомьтесь с документами, чтобы узнать, как использовать Q ()

Комментарии:

1. Это не работает, F () не соответствует аргументам в этом примере…