Невозможно использовать Case, When, Then в наборе запросов django

мои модели следующие

class Loan(models.Model):
  loan_value = models.IntegerField()
  channel_seller = models.ForeignKey(ChannelSeller, on_delete=models.CASCADE)


class ChannelSeller(models.Model):
    LEVEL_CHOICES = (
        ('1','Business Consultants'),
        ('2','Unit Managers'),
        ('3','Account Managers'),
        ('4','Branch Managers'),
    )
    level = models.CharField(max_length=2, choices = LEVEL_CHOICES, null = True, blank = True)
    pin_no = models.CharField(max_length=255)
    unit_manager = models.ForeignKey('self', limit_choices_to = {"level": '2'}, on_delete=models.DO_NOTHING, null = True, blank = True, related_name='unit_manager_2')

Кредит может быть создан бизнес_консультантом или юнит_менеджером. Каждый бизнес_консультант будет иметь unit_manager, однако unit_manager будет иметь unit_manager как пустой

С учетом сказанного,

Я пытаюсь отсортировать запрос по полю unit_manager, используя case, when, then следующим образом

transactions = Loan.objects.annotate(unit_manager_pin = Case(When('channel_seller__level' == '2', then='channel_seller_pin_no'), When('channel_seller__level' == '1', then='channel_seller__unit_manager__pin_no'))).filter(channel_seller__level__in = ['1','2']).order_by('channel_seller__level')

Однако этот запрос выдает ошибку __init__() takes either a Q object or lookups as keyword arguments

Необходимо применить условие, похожее на фильтр, а также получить значение с помощью функции F. Попробуйте сделать это.

transactions = Loan.objects.annotate(unit_manager_pin = Case(When(channel_seller__level='2', then=F('channel_seller__pin_no')), When(channel_seller__level='1', then=F('channel_seller__unit_manager__pin_no')))).filter(channel_seller__level__in = ['1','2']).order_by('channel_seller__level')

Вы составляете запрос, который будет выполняться DBM. Вы не можете использовать код Python в этом контексте ('channel_seller__level' == '2' ). См. документацию по условным выражениям .

Пожалуйста, оформляйте код разборчиво! Используйте разрывы строк внутри скобок для продолжения.

В этом случае вы просто меняете == на =, но важно понять, почему. Аргумент When аналогичен аргументу .filter. Таким образом, для проверки на большее, это будет When( field__gt = 2, ...)

Вам также необходимо использовать F для ссылки на значение в базе данных. Без F это будет (возможно, не уверен) ошибкой. (Если бы вы хотели получить фиксированное значение, вы бы использовали Value('fixed-value'))

transactions = Loan.objects.annotate(unit_manager_pin =
    Case(When('channel_seller__level' = '2', 
             then=F('channel_seller_pin_no')), 
         When('channel_seller__level' = '1',
             then=F('channel_seller__unit_manager__pin_no'))
         )
    ).filter(
        ...
        
Вернуться на верх