开发者

how to get the first element and the last element using django , Location.objects.all()

this is my code.

obj_list=Location.objects.all()
first_element=obj_list[0]
last_element=obj_list[-1]

then,

return render_to_response(template_name, {
        'first_element':first_element,
        'last_element':last_element,
    })

and in the template:

{{ first_element.terminal_id}} {{last_elem开发者_StackOverflow社区ent.terminal_id}}

but it show nothing ,

what can i do ,

thanks


Have a look at http://docs.djangoproject.com/en/dev/topics/db/queries/#limiting-querysets

Negative indexing (i.e. Entry.objects.all()[-1]) is not supported.

Try:

first_element = Location.objects.all()[0]
last_element = Location.objects.all().reverse()[0]

-- Update 8/6/17 --

Based on @MisterRios' comment,

As of 1.6 Django supports using .first() and .last() on querysets: first_element = Location.objects.first() last_element = Location.objects.last()

Refer: https://docs.djangoproject.com/en/1.7/ref/models/querysets/#django.db.models.query.QuerySet.first


You might not be able to negatively index a queryset, but you can put that queryset into a list, and then index away.

locations = list(Location.objects.all())
first_element = locations[0]
last_element = locations[-1]

This is horribly inefficient though, and should only be used if there are a small number of locations in your table, and you want to keep the code simple. Otherwise, if there is a genuine need to make this efficient, see @pterk's answer, involving aggregates and Min/Max.


To get the last one [-1] try Location.objects.latest('id') as seen in documentation:

https://docs.djangoproject.com/en/1.3/ref/models/querysets/#latest


obj_list is an instance of QuerySet, and QuerySet has own methods:

obj_list.latest('pk')
obj_list.earliest('pk')
obj_list.first() 
obj_list.last()


Last : - Location.objects.reverse()[0]

OR

          Location.objects.all()[Location.objects.count()-1]  // BAD WAY

First: Location.objects.all()[0]

Note: Negative indexing is not supported. so, Location.objects.all()[-1] will throw you an AssertionError


In case anyone came here for getting first and last item of a related model - the only way of doing it efficiently are to turn related field into list or use count() to get index of last item (using Django 1.11.2):

class Parent(models.Model):
    name = models.CharField(max_length=200)


class Child(models.Model):
    parent = models.ForeignKey(Parent, on_delete=models.CASCADE, related_name='children')
    name = models.CharField(max_length=200)


class ParentTest(TestCase):
    def test_parent(self):
        # create some data
        for p in range(10):
            parent = Parent.objects.create(name=p)
            for c in range(10):
                parent.children.create(name=c)

        with self.assertRaises(AssertionError):  # can't negative index
            parents = Parent.objects.prefetch_related('children')
            for parent in parents:
                first = parent.children.all()[0]
                last = parent.children.all()[-1]

        with self.assertNumQueries(22):  # 2 for prefetch and 20 for access
            parents = Parent.objects.prefetch_related('children')
            for parent in parents:
                first = parent.children.first()
                last = parent.children.last()

        with self.assertNumQueries(22):  # 2 for prefetch and 20 for access
            parents = list(Parent.objects.prefetch_related('children'))
            for parent in parents:
                first = parent.children.first()
                last = parent.children.last()

        with self.assertNumQueries(12):  # 2 for prefetch and 10 for last
            parents = Parent.objects.prefetch_related('children')
            for parent in parents:
                first = parent.children.all()[0]
                last = parent.children.reverse()[0]

        with self.assertRaises(AssertionError):  # can't negative index
            parents = list(Parent.objects.prefetch_related('children'))
            for parent in parents:
                first = parent.children.all()[0]
                last = parent.children.all()[-1]

        with self.assertNumQueries(2):  # 2 for prefetch
            parents = Parent.objects.prefetch_related('children')
            for parent in parents:
                children = list(parent.children.all())
                first = children[0]
                last = children[-1]

        with self.assertNumQueries(2):
            parents = Parent.objects.prefetch_related('children')
            for parent in parents:
                first = parent.children.all()[0]
                last = parent.children.all()[parent.children.count() - 1]


it may be quite inefficient

obj_list=Location.objects.all()
first_element=obj_list[0]
last_element=obj_list[len(obj_list)-1]


If you have a way to sort the location objects look into Aggregates (Min and Max). http://docs.djangoproject.com/en/dev/topics/db/aggregation/

You might be tempted do Min and Max on id but try to avoid that as the order of ids is not guaranteed (at least not accross various database engines)


Issues query:


ERROR 2021-05-17 02:14:20,744 log 30 139680490260288 Internal Server Error: /camp/
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/opt/project/apps/web/views.py", line 419, in camp
    amount_by_daily = draw_amount_by_daily()
  File "/opt/project/apps/web/charts.py", line 16, in draw_amount_by_daily
    daily_list = DailyReport.objects.filter(category="daily_all").order_by('create_at').values("create_at")[-12:]
  File "/usr/local/lib/python3.7/site-packages/django/db/models/query.py", line 288, in __getitem__
    "Negative indexing is not supported."
AssertionError: Negative indexing is not supported.
daily_list = DailyReport.objects.filter(category="daily_all").order_by('create_at').values("create_at")[-12:]

How to fixed it?

daily_list = DailyReport.objects.filter(category="daily_all").order_by('-create_at').values("create_at")[:12]
result = list(reversed(daily_list))

Tips:

In [164]: l1 = [1,2,3,4,5,6]

In [165]: l1 = list(reversed(l1))

In [166]: l1
Out[166]: [6, 5, 4, 3, 2, 1]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜