我有几个用户的博客。
我想在帖子页面添加“next post”和“previous post”按钮,我希望它们链接到同一作者撰写的下一篇/上一篇文章。
我知道我可以这样做:
var whatever = Array(5).fill('');
但这将链接到任何作者撰写的下一篇文章。
我可以以某种方式过滤特定作者吗?
或者有更好的方法来获取下一个/上一个帖子的网址吗?
答案 0 :(得分:2)
这是一个通用函数(来自django-baseclasses),可以满足您的需求。它从自定义查询集中获取下一个或上一个项目(在您的情况下对作者进行过滤),并尊重模型Meta
类中的顺序(您需要一个明确的Meta.ordering
才能使其工作)< / p>
from functools import reduce
from django.db import models
def get_model_attr(instance, attr):
"""Example usage: get_model_attr(instance, 'category__slug')"""
for field in attr.split('__'):
instance = getattr(instance, field)
return instance
def next_or_prev_in_order(instance, prev=False, qs=None, loop=False):
"""Get the next (or previous with prev=True) item for instance, from the
given queryset (which is assumed to contain instance) respecting
queryset ordering. If loop is True, return the first/last item when the
end/start is reached. """
if not qs:
qs = instance.__class__.objects
if prev:
qs = qs.reverse()
lookup = 'lt'
else:
lookup = 'gt'
q_list = []
prev_fields = []
if qs.model._meta.ordering:
ordering = list(qs.model._meta.ordering)
else:
ordering = []
for field in (ordering + ['pk']):
if field[0] == '-':
this_lookup = (lookup == 'gt' and 'lt' or 'gt')
field = field[1:]
else:
this_lookup = lookup
q_kwargs = dict([(f, get_model_attr(instance, f))
for f in prev_fields])
key = "%s__%s" % (field, this_lookup)
q_kwargs[key] = get_model_attr(instance, field)
q_list.append(models.Q(**q_kwargs))
prev_fields.append(field)
try:
return qs.filter(reduce(models.Q.__or__, q_list))[0]
except IndexError:
length = qs.count()
if loop and length > 1:
# queryset is reversed above if prev
return qs[0]
return None
像这样使用它:
class Post(models.Model):
...
def prev_by_author(self):
qs = Post.objects.filter(author=self.author)
return next_or_prev_in_order(self, True, qs)
def next_by_author(self):
qs = Post.objects.filter(author=self.author)
return next_or_prev_in_order(self, False, qs)