假设Q&amp;网站。在结束点/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
但是,我认为这种操作非常昂贵,只要请求问题Ques
,它就会查询所有问题(/q/id
个对象)。
我看到的一种可能的方法是使用链接列表的概念,其中下一个&amp;以前的对象id可以存储在当前对象中。
Ques
模型中可能有两个字段
class Ques(models.Model):
prev_q_id = models.IntegerField()
next_q_id = models.IntegerField()
每当创建,编辑和删除新的Ques对象时,都会更新这些内容。这确保了我只查询一个对象。但是,我想知道这是否是一个好方法。如果不是我怎么办?
答案 0 :(得分:2)
在订购结构上使用链接列表毫无意义,因为您的数据库已经为您提供了一个有序的记录列表,您可以根据需要订购数据,从而获得所需的任何项目。
这是一种可以为您提供所需内容的方法
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
使用classmethod在这里更有用,您只需获取下一个或上一个最接近的记录。如果没有记录,则获得None
答案 1 :(得分:0)
使用链接列表的方法是可行的,但您无需更改数据模型即可支持所需内容。相反,您可以简单地为所有大于主键的问题创建一个游标,然后阅读第一个。
请记住,objects.all()实际上并不读取所有对象。它只是为数据创建一个游标。您可以将光标视为数据库关于如何检索数据的“行动计划”。只有当您实际获取数据时,它才会开始读取数据库记录。
你想要的基本上是在sql中。
select * from Question where pk > question.pk order by pk
在django中,这就像是
all_q = Ques.objects.all()
all_q.filter(pk__gt=question.pk)
all_q.order_by('pk') # not really necessary as this is done implicitly
next_q = all_q.first()
对于之前的记录,您也可以这样做,但使用相反的顺序或只是调用“last”而不是第一个。