Django - как фильтровать новости по категориям + пагинатор.

    blazer |   15.04.2016 |   10:01:43 |   Django |

Всем привет!

Сегодня расскажу, как я боролся с пагинацией страниц внутри категорий. Была задача сделать категории и отфильтровать все записи блога по категориям + разбиение новостей пагинатором, чтоб к примеру была возможность выводить на одной странице не все записи категории а только к примеру первые 5 и т.д.

Итак приступим.


Создаем модель Category в models.py

class Category(models.Model):
    class Meta():
        db_table = 'category'
        ordering = ['name']
        verbose_name = 'Категория'
        verbose_name_plural = 'Категории'

    name = models.CharField(max_length=150, unique=True, verbose_name='Категория')
    slug = models.SlugField(verbose_name='Транслит', null=True)

    def __unicode__(self):
        return self.name

Пишем функцию - обработчик, которая будет делать фильтровать записи по категориям и выводить пагинатор.

def category(reguest, slug):
    category = Category.objects.get(slug=slug)
    post = BlogPost.objects.filter(category=category)
    paginator = Paginator(post, 2)
    page = reguest.GET.get('page')
    try:
        post = paginator.page(page)
    except PageNotAnInteger:
        post = paginator.page(1)
    except EmptyPage:
        post = paginator.page(paginator.num_pages)
    return render(reguest, 'category.html', {
        'category': category,
        'page': page,
        'post': post})

Как видим функция принимает два параметра 1 запрос и slug то что мы прописали в модели.

category = Category.objects.get(slug=slug) - Получаем категории из базы данных.
post = BlogPost.objects.filter(category=category) - Получаем записи блога и применяем сразу фильтрацию по категориям. Это означает, если зайти в категорию к примеру Django в которой есть на текущий момент 12 записей, то они все выведутся на странице.
paginator = Paginator(post, 2) - Пишем пагинатор. Вставляем в пагинатор переменную в моем случае это post, которая тянет записи из базы данных и количество 2 - это сколько будет выводится новостей на странице данной категории.
page = reguest.GET.get('page') - Пишем GET запрос по которому будем перебирать новости вперед/назад внутри категории.

Далее пишем такую конструкцию

try:
    post = paginator.page(page)
except PageNotAnInteger:
    post = paginator.page(1)
except EmptyPage:
    post = paginator.page(paginator.num_pages)

Параметр (1) - это означает с какой записи начинать переход т.е. с первой.

Ну и возвращаем все это дело так.

return render(reguest, 'category.html', {
    'category': category,
    'page': page,
    'post': post})

Теперь напишем урл для этой функции

url(r'^category/(?P<slug>[-\w]+)/$', views.category, name='category'),

Ну и выводим все это дело в шаблон!

<div class="row">
        <div class="col-lg-12" align="center">
            <ul class="pagination">
                {% if post.has_previous %}
                    <li class="arrow"><a href="/blog/category/{{ category.slug }}?page={{ pag }}{{ post.previous_page_number }}">&laquo;</a></li>
                {% else %}
                    <li class="disabled"><a href="">&laquo;</a></li>
                {% endif %}
                {% for pag in post.paginator.page_range %}
                    {% if pag == post.number %}
                        <li class="active"><a href="/blog/category/{{ category.slug }}?page={{ pag }}">{{ pag }}</a></li>
                    {% else %}
                        <li><a href="/blog/category/{{ category.slug }}?page={{ pag }}">{{ pag }}</a></li>
                    {% endif %}
                {% endfor %}
                {% if post.has_next %}
                    <li class="arrow"><a href="/blog/category/{{ category.slug }}?page={{ pag }}{{ post.next_page_number }}">&raquo;</a></li>
                {% else %}
                    <li class="disabled"><a href="">&raquo;</a></li>
                {% endif %}
            </ul>
        </div>
    </div>

И можем наслаждаться результатом наших трудов, как показано на видео.

Делал согласно документации Django и исползовал запрос в поиске django pagination

Ваши комментарии

Комментарии могут оставлять только зарегистрированые пользователи!

Disqus - комментарии

blog comments powered by Disqus