【问题标题】:Django queryset for Case object and When Object, ---Case对象和When Object的Django查询集,---
【发布时间】:2021-07-12 14:39:26
【问题描述】:

我希望在以下方面获得您的帮助: 我有两个模型父模型和一个子模型:

class Rate(models.Model):
        RATE_VOLTAGE_CHOICES = (
            (BAJA_TENSION, "Low tension"),
            (MEDIA_TENSION, "Mid tension"),
            (ALTA_TENSION, "High tension")
        )
        rate_type = models.CharField(max_length=1, choices=RATE_TYPE_CHOICES, default="0")

class ParentRate(models.Model):
    rate = models.ForeignKey(Rate, on_delete=models.SET_NULL, blank=True, null=True

)

所以前端想要通过低张力、中张力和高张力“过滤”rate_type 选择作为字符串,他们发送字符串 所以我正在尝试使用 When Case 对象,以便我可以过滤:

rates = ParentRate.objects.annotate(rate_voltage=Case(
                    When(rate__rate_type=Rate.BAJA_TENSION, then=Value('Low tension')),
                    When(rate__rate_type=Rate.MEDIA_TENSION, then=Value('Mid tension')),
                    When(rate__rate_type=Rate.ALTA_TENSION, then=Value('High tension')),
                    default=Value('Low tension'),
                )

            )

但我收到以下错误:

django.core.exceptions.FieldError: Cannot resolve expression type, unknown output_field

【问题讨论】:

    标签: python-3.x django postgresql django-models django-queryset


    【解决方案1】:

    作为 documented 在 Aggregate() 表达式中

    output_field 参数需要一个模型字段实例,例如 IntegerField() 或 BooleanField(),Django 将在其中加载 从数据库中检索后的值。

    请注意,仅当 Django 无法使用时才需要 output_field 确定结果应该是什么字段类型。复杂的表达式 混合字段类型应定义所需的 output_field。为了 例如,将 IntegerField() 和 FloatField() 添加在一起应该 可能已经定义了 output_field=FloatField()。

    在你的情况下是 CharField

    rates = ParentRate.objects.annotate(rate_voltage=Case(
                        When(rate__rate_type=Rate.BAJA_TENSION, then=Value('Low tension')),
                        When(rate__rate_type=Rate.MEDIA_TENSION, then=Value('Mid tension')),
                        When(rate__rate_type=Rate.ALTA_TENSION, then=Value('High tension')),
                        default=Value('Low tension'),
                        output_field=CharField()
                    ),
    
                )
    

    【讨论】:

    • 我认为 output_field 应该添加在Case args 定义下而不是annotate args 下。您的查询引发异常:TypeError: QuerySet.annotate() received non-expression(s): <django.db.models.fields.CharField>.
    【解决方案2】:

    您需要在查询中添加output_field,如下例所示:

    from django.db.models import fields
    
    
    rates = ParentRate.objects.annotate(rate_voltage=Case(
                        When(rate__rate_type=Rate.BAJA_TENSION, then=Value('Low tension')),
                        When(rate__rate_type=Rate.MEDIA_TENSION, then=Value('Mid tension')),
                        When(rate__rate_type=Rate.ALTA_TENSION, then=Value('High tension')),
                        default=Value('Low tension'),
                        output_field=fields.CharField()  # if the output field is a string
                    )
    
                )
    

    欲了解更多信息:Django docs: Aggregate() expressions

    【讨论】:

      猜你喜欢
      • 2022-12-15
      • 2017-05-30
      • 2021-03-15
      • 2011-04-17
      • 2014-11-29
      • 2017-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多