我有一个包含这些字段的模型:
class ModelA(models.Model):
parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.PROTECT, related_name='child')
number = models.PositiveIntegerField()
text_code = models.CharField(max_length=255, blank=True, null=True)
我想使用带有这些规则的注释和案例对该模型进行查询:
- 当 parent 为 null 时,它返回 text_code 字段
- 当 parent 不为 null 时返回 parent__number 字段
我可以用 PostgreSQL 中的 SQL 实现它,例如:
CASE WHEN "ModelA"."parent_id" IS NOT NULL
THEN T3."number"**::integer**
ELSE "ModelA"."text_code"**::integer** END AS "control_field"
但我无法使用 Django ORM 实现。我尝试了以下方法:
query = ModelA.objects.all().select_related('parent').annotate(
control_field=Case(
When(parent_id__isnull=False, then='parent__number'),
default='text_code',
output_field=IntegerField(),
),
)
但是当我调用查询结果时,它引发了以下错误:
django.db.utils.ProgrammingError: CASE types character varying and integer cannot be matched
我知道这是一个数据库错误,因为 django 构造的 SQL 结果没有添加 ::integer。
CASE WHEN "ModelA"."parent_id" IS NOT NULL
THEN T3."number"
ELSE "ModelA"."text_code" END AS "control_field"
我该如何解决这个问题?我正在使用 Django 1.11
最佳答案
答案是,使用 Cast:
query = ModelA.objects.all().select_related('parent').annotate(
control_field=Case(
When(parent_id__isnull=False, then=Cast('parent__number', IntegerField())),
default=Cast('text_code', IntegerField()),
output_field=IntegerField(),
),
)
关于python - 在 Django 中使用具有不同字段类型的注释和案例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51518005/