说我有一个按创建日期排序的照片列表,如下所示:
class Photo(models.Model):
title = models.Char()
image = models.Image()
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ('-created',)
我有一个任意的Photo对象photo_x。有没有一种简单的方法可以在查询集中按位置查找上一张和下一张照片?另外,如果我只是一张或两张照片,我想在开始/结束时使用它并且不会失败。
答案 0 :(得分:32)
你很幸运! Django默认为get_next_by_foo
&创建get_previous_by_foo
和DateField
方法。 DateTimeField
,只要他们没有null=True
。
例如:
>>> from foo.models import Request
>>> r = Request.objects.get(id=1)
>>> r.get_next_by_created()
<Request: xyz246>
如果到达集合的末尾,它将引发DoesNotExist
异常,您可以轻松地将其作为触发器返回到集合的开头:
>>> r2 = r.get_next_by_created()
>>> r2.get_next_by_created()
...
DoesNotExist: Request matching query does not exist.
进一步阅读:Extra instance methods
答案 1 :(得分:2)
get_next_by_foo和get_previous_by_foo非常方便,但非常有限 - 如果您在多个字段或非日期字段中进行订购,它们将无法帮助您。
我写了django-next-prev作为同一想法的更通用的实现。在您的情况下,您可以这样做,因为您已经在Meta中设置了排序:
from next_prev import next_in_order, prev_in_order
from .models import Photo
photo = Photo.objects.get(...)
next = next_in_order(photo)
prev = prev_in_order(photo)
如果您想在其他一些字段组合上订购,只需传递查询集:
photos = Photo.objects.order_by('title')
photo = photos.get(...)
next = next_in_order(photo, qs=photos)
答案 2 :(得分:0)
对于jathanism的答案,它有用,但 get_next_by_FOO 和 get_previous_by_FOO 会忽略毫秒...例如,它不适用于在循环中创建的对象:
for i in range(100):
Photo.objects.create(title='bla', ...)
obj = Photo.objects.first()
obj.get_previous_by_created()
DoesNotExist: Photo matching query does not exist.