0

I have a model similar to this:

class Tree(models.Model):
   description = models.CharField(max_length = 255, null = False, blank = False)
   parent = models.ForeignKey("Tree", null = True, blank = True, on_delete = models.CASCADE)
   
   class Meta:
     ordering = ['description', '-id']

I need to find the latest record for each parent.

I tried with this:

latests = Tree.objects.values("parent").annotate(last = Max("pk"))

The result is not correct because the SQL query is:

SELECT parent_id, MAX(id) AS last FROM tree GROUP BY id;

The ORM translates the foreign key to the source and does not use the value inside the field. Is there a way not to "follow" the foreign key and to use instead the value of the field?

The model generated in the PostgreSQL database the table named tree with three columns:

Column      | Type
------------+-----------------------
id          | integer
description | character varying(255)
parent_id   | integer

With this data:

id  | description | parent_id
----+-------------+----------
1   | A           | 1
2   | B           | 2
3   | C           | 1 
4   | D           | 1
5   | E           | 2 

I want this result:

last | parent_id
-----+----------
   5 |         2
   4 |         1

I can do this simply in SQL with:

select max(id) as last, parent_id from tree group by parent_id
Christian
  • 51
  • 1
  • 6
  • 1
    Can you document what the query you want should look like in SQL? – pygeek Sep 16 '20 at 19:56
  • select parent_id, max(id) from tree group by parent_id. The issue seems to be the same as https://code.djangoproject.com/ticket/24748 for MySQL. I'm using postgresql – Christian Sep 16 '20 at 20:05
  • That's the query you got according to your question, not the query you want. Please post the query that you would like (ie: JOIN query). Also, the bug you referenced was fixed and not present in your example as it is correctly grouping by id. – pygeek Sep 16 '20 at 20:15
  • No. This is the query I want with "GROUP BY parent_id". The query the system generates has "GROUP BY id". I added also the table definition to the question to be more clear. – Christian Sep 16 '20 at 20:23
  • ok, please update your question with those details. – pygeek Sep 16 '20 at 20:24
  • I've tested your code in the latest version of django (3.8.5). It correctly groups by parent_id. What version of Django are you using? Also, there may be a bug in your actual code that is not captured in the analogue you posted. Output where "values" is the table name: `'SELECT "values_tree"."parent_id", MAX("values_tree"."id") AS "pk__max" FROM "values_tree" GROUP BY "values_tree"."parent_id"'` – pygeek Sep 16 '20 at 20:53
  • Found! I have also an ordering in Meta. I've just updated the question. If you try with this definition (with Meta) the resulting query is not correct, or at least is not the expected one. – Christian Sep 16 '20 at 21:03
  • Nice. Now add and accept an answer to your own question so that others know how to fix a similar issue. – pygeek Sep 16 '20 at 21:12

1 Answers1

0

Finally I found a possible workaround: I deleted the ordering in Meta class and the result is the expected one.

Christian
  • 51
  • 1
  • 6