Search code examples
pythondjangolistviewpaginationdetailview

Pagination in DetailView [Django]


I have Article and ArticleCategory in my model. Article has many categories.

MODELS

class ArticleCategory(Created):
    category_name = models.CharField(max_length=128)
    slug = models.SlugField(null=False, unique=False)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.category_name)
        return super().save(*args, **kwargs)

    def __str__(self):
        return self.category_name

class Article(Created):
    title = models.CharField(max_length=120)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    snippet = models.TextField(null=False)  # ustawić max_lenght
    body = RichTextField(null=False)
    category = models.ManyToManyField(ArticleCategory, related_name='articles')  # TODO: ustawić on_delete
    image = models.ImageField(blank=True, null=True, upload_to='article_image/')
    slug = models.SlugField(null=False, unique=False)

    def save(self, *args, **kwargs):  
        if not self.slug:
            self.slug = slugify(self.title)
        return super().save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('news:article_detail', kwargs={'pk': self.pk, 'slug': self.slug})

Also I have Url to specific category with all Articles with this category:

URL

urlpatterns = [
    path('show/<int:pk>/<slug:slug>', ArticleDetailView.as_view(), name='article_detail'),
    path('all/', AllArticlesListView.as_view(), name='all_articles_list'),
    path('category/<slug:slug>/', CategoryArticlesList.as_view(), name='category_articles_list'),
]

In the VIEW i created

class CategoryArticlesList(DetailView):
    template_name = 'news/category_articles_list.html'
    model = ArticleCategory

And finally template CATEGORY_ARTICLES_LIST.HTML

SPECIFIC CATEGORY: {{ articlecategory.category_name | upper }}

AND ALL NEWS WITH THIS CATEGORY
{% for article in articlecategory.articles.iterator reversed %}
    <h3>{{ article.title }}</h3> <br>
    {{ article.body | safe }} <br>
{% endfor %}

My question is... How can I make Pagination to all specific category articles in Views? If I use ListView in class CategoryArticlesList there will be big problem with query form me... I dont know what I should do.


Solution

  • A DetailView does not do pagination, since, well there is only a single object. You can howver make it a ListView and add some logic to pass the articlecategory:

    from django.shortcuts import get_object_or_404
    
    class ArticlesByCategoryListView(ListView):
        template_name = 'news/category_articles_list.html'
        model = Article
        queryset = Article.objects.order_by('-pk')
        paginate_by = 25
    
        def get_queryset(self, *args, **kwargs):
            return super().get_queryset(*args, **kwargs).filter(
                category__slug=self.kwargs['slug']
            )
    
        def articlecategory(self):
            return get_object_or_404(ArticleCategory, slug=self.kwargs['slug'])

    then in the template, we can render this with:

    SPECIFIC CATEGORY: {{ view.articlecategory.category_name|upper }}
    
    AND ALL NEWS WITH THIS CATEGORY
    {% for article in page_obj %}
        <h3>{{ article.title }}</h3> <br>
        {{ article.body|safe }} <br>
    {% endfor %}