Джанго - функция перехода на предыдущий и следующий пост
Всем доброго времени суток!
Проблема:
Есть категории со связанными постами. Нужно сделать, что бы на странице ПОСТ были 2 кнопки перехода на предыдущую и следующую страницу. Если предыдущей странице поста категории нет, то переход на главную, а если нет следующей странице поста, то на страницу следующей по порядку категории.
Я всю голову сломал, но даже логики этого выстроить не могу. Прошу помощи у знающих! Заранее спасибо за ответ!
Models
class category(models.Model):
slug = models.SlugField(max_length=266, unique=True, db_index=True, verbose_name=('URL'))
description = models.TextField(max_length=700, verbose_name=('Описание'), blank=False)
def __str__(self):
return self.slug
def get_absolute_url(self):
return reverse('category', kwargs={'category_slug': self.slug})
class post(models.Model):
slug = models.SlugField(max_length=266, unique=True, db_index=True, verbose_name=('URL'))
description = models.TextField(max_length=700, verbose_name=('Описание'), blank=False)
cat = models.ForeignKey('category', on_delete=models.PROTECT, null=True)
def __str__(self):
return self.slug
def get_absolute_url(self):
return reverse('post', kwargs={'post_slug': self.slug})
Views
def ContentСategory(request, category_slug):
category = get_list_or_404(post, slug=category_slug)
category=category.objects.filter(slug=category_slug)
return render(request, 'content/category.html',{'category':category})
def content_post(request, category_slug, post_slug):
post = get_list_or_404(post, slug=post_slug)
post = post.objects.filter(slug=post_slug, cat__slug=category_slug)
return render(request, 'content/post.html', {'post': post}
URLS
urlpatterns = [
path('', views.ContentHome.as_view(), name='homepage'),
path('<slug:category_slug>', views.ContentCategory, name='category'),
path('<slug:category_slug>/<slug:post_slug>', views.ContentPost, name='post'),
]
Ответы (1 шт):
Автор решения: Andrey Maslov
→ Ссылка
Тут непонятно как именно находить предыдущий и следующий, так как не ясна сортировка по которой они должны отображаться. Предположим, что нас интересует сортировка по slug. Тогда можно сделать как-то так
def get_next_post(post_slug, category_slug):
found = post.objects.first(cat__slug=category_slug, slug__gt=post_slug).order_by("slug")
if not found: # последний пост в данной категории, найдем первый в следующей
found = post.objects.first(cat__slug_gt=category_slug).order_by("slug")
return found
def get_previous_post(post_slug, category_slug):
found = post.objects.last(cat__slug=category_slug, slug__lt=post_slug).order_by("slug")
# тут по задаче стоит, сразу ссылку домой, но я бы сделал навигацию одинаковой,
# предыдущий для первого поста в категории - это последний пост в предыдущей категории
if not found:
found = post.objects.last(cat__slug_lt=category_slug).order_by("slug")
return found
def content_post(request, category_slug, post_slug):
found_post = get_object_or_404(post, slug=post_slug, cat__slug=category_slug)
next = get_next_post(post_slug, category_slug)
previous = get_previous_post(post_slug, category_slug)
if next:
next_url = next.get_absolute_url()
next_title = "next"
else:
next_url = reverse("homepage")
next_title = "home"
if previous:
previous_url = previous.get_absolute_url()
previous_title = "previous"
else:
previous_url = reverse("homepage")
previous_title = "home"
return render(
request,
"content/post.html",
{
"post": found_post,
"next_url": next_url,
"next_title": next_title,
"previous_url": previous_url,
"previous_title": previous_title,
},
)