【问题标题】:Is there a clever way to get the previous/next item using the Django ORM?有没有一种聪明的方法来使用 Django ORM 获取上一个/下一个项目?
【发布时间】:2010-12-28 05:02:29
【问题描述】:

假设我有一个按创建日期排序的照片列表,如下:

class Photo(models.Model):
    title = models.Char()
    image = models.Image()
    created = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ('-created',)

我有一个任意的照片对象 photo_x。有没有一种简单的方法可以按查询集中的位置查找上一张和下一张照片?另外,如果我在开始/结束时,我想环绕一下,如果只有 1 或 2 张照片,它不会失败。

【问题讨论】:

    标签: python django django-models


    【解决方案1】:

    你很幸运! Django默认为DateFieldDateTimeField创建get_next_by_fooget_previous_by_foo方法,只要它们没有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

    【讨论】:

    • 谢谢,我知道存在这样的东西,只是想不出来。
    • 我很高兴这正是您所寻找的。很高兴能够提供帮助。
    【解决方案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)
    

    【讨论】:

      【解决方案3】:

      对于 jathanism 的回答,它很有用,但是 get_next_by_FOOget_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.
      

      【讨论】:

      • 你可能想做 obj.get_next_by_created();第一项将有最早的时间戳,因此没有以前的。
      猜你喜欢
      • 2020-08-28
      • 2015-04-07
      • 2011-08-18
      • 2021-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-24
      • 2016-01-29
      相关资源
      最近更新 更多