5
I have a model in Django with fields largura
and comprimento
, and would like to filter it by area:
class Projeto(models.Model):
largura = models.DecimalField(decimal_places=0, max_digits=4, default=0)
comprimento = models.DecimalField(decimal_places=0, max_digits=4, default=0)
I tried the following query:
Projeto.objects.annotate(area=F('largura')*F('comprimento')).filter(area__lte=1000)
However, it didn’t work: query returned all the lines of Projeto
, including those that have larger area than 1000
. What am I doing wrong?
I checked the SQL being generated by the query (formatted for readability):
>>> print Projeto.objects.annotate(area=F('largura')*F('comprimento')).filter(area__lte=1000).query
SELECT "mcve_projeto"."id", "mcve_projeto"."largura", "mcve_projeto"."comprimento",
("mcve_projeto"."largura" * "mcve_projeto"."comprimento") AS "area"
FROM "mcve_projeto"
WHERE ("mcve_projeto"."largura" * "mcve_projeto"."comprimento") <= 1000
as well as the database creation SQL (idem):
python manage.py sqlmigrate mcve 0001
BEGIN;
CREATE TABLE "mcve_projeto" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"largura" decimal NOT NULL,
"comprimento" decimal NOT NULL);
COMMIT;
and created an example in Sqlfiddle (note: I am using Sqlite). It worked normal. Where can be the problem?
A friend of mine doesn’t have an account in the OS, so here’s a possible solution that he said could work:
Projeto.objects.annotate(area=F('largura')*F('comprimento')).filter(area__lte=1000).values('area')
– mazulo
@Thanks to the suggestion, but: 1) did not work, continued returning areas larger than 1000; 2) I want the complete objects, not only the area, so use
values
is not a good option for me.– mgibsonbr
What version of Django are you using?
– mazulo
@Mazulo 1.9 on Linux and 1.8 on Windows. Same result on both. Python 2.7.
– mgibsonbr