1

I have a model:

class List:
    data = ...
    previous = models.ForeignKey('List', related_name='r1')
    obj = models.ForeignKey('Obj', related_name='nodes')

This is one direction list containing reference to some obj of Obj class. I can reverse relation and get some list's all elements refering to obj by:

obj.nodes

But how Can I get the very last node? Without using raw sql, genering as little SQL queries by django as can.

santo
  • 43
  • 3
  • 5
  • In raw sql it would be sth like: select id, data from LISTS where id not in (SELECT previous from LISTS); where LISTS is somewhat obj.nodes (another select) – santo Aug 10 '11 at 12:57

5 Answers5

4

obj.nodes is a RelatedManager, not a list. As with any manager, you can get the last queried element by

obj.nodes.all().reverse()[0]

This makes sense anyway only if there is any default order defined on the Node's Meta class, because otherwise the semantic of 'reverse' don't make any sense. If you don't have any specified order, set it explicitly:

obj.nodes.order_by('-pk')[0]
rewritten
  • 16,280
  • 2
  • 47
  • 50
1

I see this question is quite old, but in newer versions of Django there are first() and last() methods on querysets now.

wobbily_col
  • 11,390
  • 12
  • 62
  • 86
1
len(obj.nodes)-1 

should give you the index of the last element (counting from 0) of your list

so something like

obj.nodes[len(obj.nodes)-1]

should give the last element of the list i'm not sure it's good for your case, just give it a try :)

Samuele Mattiuzzo
  • 10,760
  • 5
  • 39
  • 63
0

Well, you just can use [-1] index and it will return last element from the list. Maybe this question are close to yours:

Getting the last element of a list in Python

Community
  • 1
  • 1
Dracontis
  • 4,184
  • 8
  • 35
  • 50
0

for further reading, Django does not support negative indexing and using something like

obj.nodes.all()[-1]

will raise an error.

in newer versions of Django you can use last() function on queryset to get the last item of your list.

obj.nodes.last()

another approach is to use len() function to get the index of last item of a list

obj.nodes[len(obj.nodes)-1]