如何使用链接列表在 django 中查找下一个和上一个对象?

Sur*_*rya 2 python django django-models

假设有一个问答网站。当在终点打开问题时/q/<id2>,它还应该提供到下一个/q/<id1>、上一个问题的链接/q/<id3>。假设该表是按pk值或时间戳的顺序排列的。

这可以通过创建如下我现在使用的方法来简单地解决:

def next_q(self):
    # Ques model contain all questions
    # this method is a model method of Ques
    all_q = Ques.objects.all()
    q = None
    count = 1
    if count < all_q.count():
        try:
            q = all_q.get(pk=self.pk + count)
            break
        except ObjectDoesNotExist:
            count += 1
    return q
Run Code Online (Sandbox Code Playgroud)

然而,我认为这种操作的成本足够高,Ques每当有问题/q/id被请求时,它都会查询所有问题(对象)。

我看到的一种可能的方法是使用链表的思想,其中下一个和上一个对象 ID 可以存储在当前对象中。

Ques模型中可能有两个字段

class Ques(models.Model):
    prev_q_id = models.IntegerField()
    next_q_id = models.IntegerField()
Run Code Online (Sandbox Code Playgroud)

每当创建、编辑、删除新的 Ques 对象时,这些都会更新。这确保我只会查询一个对象。但是我想知道这是否是一个好方法。如果不是我还能怎么办?

Fal*_*gel 5

在有序结构上使用链接列表是没有意义的,因为您的数据库已经为您提供了有序记录列表,并且您可以根据需要对数据进行排序来访问您想要的任何项目。

这是一种可以返回你想要的结果的方法

class Ques(Model):
    ....

    @classmethod
    def get_next(cls, current_id):  # current_id is the id of current record
        try:
            return cls.objects.filter(id__gt=current_id).order_by("id")[0]
       except:
            return None

    @classmethod
    def get_previous(cls, current_id):
        try:
            return cls.objects.filter(id__lt=current_id).order_by("-id")[0]
        except:
            return None
Run Code Online (Sandbox Code Playgroud)

在这里使用classmethod更有用,您只需获取下一个或上一个最接近的记录即可。如果没有记录,那么你会得到None