I have a model with those field:
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)
I want to make a query on that model using annotate and Case with those rules:
I can make it with SQL in PostgreSQL like:
CASE WHEN "ModelA"."parent_id" IS NOT NULL
THEN T3."number"**::integer**
ELSE "ModelA"."text_code"**::integer** END AS "control_field"
But I can't make that with Django ORM. I've tried the following:
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(),
),
)
But when I call query result, it rase the following error:
django.db.utils.ProgrammingError: CASE types character varying and integer cannot be matched
I know it is an Database error, because the SQL result from django construct doesn't have the ::integer add.
CASE WHEN "ModelA"."parent_id" IS NOT NULL
THEN T3."number"
ELSE "ModelA"."text_code" END AS "control_field"
How can I solve this? I'm working with Django 1.11
The answer is, use 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(),
),
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.