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]
精彩评论