Django ORM как использовать case when и использовать значение других объектов с фильтром?

Итак, у меня есть 2 модели:

  1. label, модели label используется для определения того, что является меткой кода "типа" пример купона тип кода 2, истек срок действия метки.
  2. модель купона используется для данных о купоне
  3. .

Итак, я хочу использовать случай, когда нужно отфильтровать данные и получить название статуса, например, если дата купона больше, чем сегодня, то он просрочен, иначе он активирован, и я хочу получить значение названия статуса из другой модели, называемой моделью label, вот моя текущая попытка

            label_status = Labels.objects.filter(label_type='coupon_status').all()

            data = Vouchers.objects.
            annotate(
                coupon_status_name=Case(
                    When(status=0, valid_dt__lte=date.today(), then=Value(system_used.filter(label_code="2").first().label_name)),
                    default=Value(label_status.filter(label_code=status).first().label_name),
                    output_field=CharField()
                )
            ).all()

я могу фильтровать первую строку в функции When(), но я не могу фильтровать объекты label в параметре default функции case, которые ссылаются на купон динамически, так как я могу это сделать? Я пытался использовать OuterRef(), как

default=Value(label_status.filter(label_code=OuterRef(status)).first().label_name)

но это дает мне эту ошибку:

Этот кверисет содержит ссылку на внешний запрос и может использоваться только в подзапросе.

любая помощь будет принята с благодарностью, и пожалуйста не просите меня изменить структуру базы данных спасибо.

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

Похоже, что Label и Coupon взаимодействуют друг с другом. Так как Label является разновидностью статуса Coupon
. вы должны попытаться добавить внешний ключ между ними. Это будет намного проще. Что-то вроде этого :

class Coupons(models.Model):
coupon_name = models.CharField(max_length=200, null=False)
coupon_desc= models.CharField(max_length=200, null=False)
valid_date = models.DateField(null=False)
status = models.IntegerField(null=False)
label_status = models.ForeignKey(Label)

Также не следует перезаписывать primary_key, Django не очень любит это, это может вызвать некоторые ошибки.

поэтому я нашел решение для этого, используя subquery() и OuterRef()

label_status = Labels.objects.filter(label_type='coupon_status').all()
data = Coupons.objects.
            annotate(
                coupon_status_name=Case(
                    When(status=0, valid_date__lte=date.today(), then=Subquery(label_status.filter(label_code="2").values('label_name'))),
                    default=Subquery(label_status.filter(label_code=OuterRef('status').values('label_name')),
                    output_field=CharField()
                )
            ).all()
Вернуться на верх