【发布时间】:2018-07-25 11:41:15
【问题描述】:
我有一个具有这些领域的模型:
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 类型字符变化和整数无法匹配
我知道这是一个数据库错误,因为 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
【问题讨论】:
-
看起来很不安全。为什么
text_code是CharField如果是数字? -
@WillemVanOnsem 这个字段来自另一个类,它可以是数字或文本,具体取决于模型
-
@WillemVanOnsem 非常感谢!我花了两天时间阅读文档,并没有看到那个功能!
标签: python django postgresql django-annotate