Невозможно использовать 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(
...