from django.views.generic import ListView, MonthArchiveView, DateDetailView
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.conf import settings
from .models import Category, Post


class PostListView(ListView):
    paginate_by = getattr(settings, 'NEWS_PER_PAGE', 10)

    def get_queryset(self):
        return Post.objects.select_related().filter(
                published=True, date__lte=timezone.now())


class PostListCategoryView(ListView):
    paginate_by = getattr(settings, 'NEWS_PER_PAGE', 10)
    template_name_suffix = '_list_category'

    def get_queryset(self):
        self.category = get_object_or_404(Category, slug=self.kwargs['slug'])
        return Post.objects.select_related().filter(
                published=True,
                date__lte=timezone.now(),
                category=self.category)

    def get_context_data(self, **kwargs):
        context = super(PostListCategoryView, self).get_context_data(**kwargs)
        context['category'] = self.category
        return context


class PostListMonthView(MonthArchiveView):
    queryset = Post.objects.filter(published=True)
    month_format = '%m'
    date_field = 'date_url'


class PostDetailView(DateDetailView):
    queryset = Post.objects.filter(published=True)
    month_format = '%m'
    date_field = 'date_url'

from django.views.generic import ArchiveIndexView, MonthArchiveView, DateDetailView
from django.shortcuts import get_object_or_404
from django.conf import settings
from .models import Category, Post


class PostListView(ArchiveIndexView):
    queryset = Post.objects.select_related().filter(published=True)
    date_field = 'date'
    paginate_by = getattr(settings, 'NEWS_PER_PAGE', 10)
    template_name_suffix = '_list'
    context_object_name = 'object_list'


class PostListCategoryView(PostListView):
    template_name_suffix = '_list_category'

    def get_queryset(self):
        qs = super(PostListCategoryView, self).get_queryset()
        self.category = get_object_or_404(Category, slug=self.kwargs['slug'])
        return qs.filter(category=self.category)

    def get_context_data(self, **kwargs):
        context = super(PostListCategoryView, self).get_context_data(**kwargs)
        context['category'] = self.category
        return context


class PostListMonthView(MonthArchiveView):
    queryset = Post.objects.filter(published=True)
    month_format = '%m'
    date_field = 'date_url'


class PostDetailView(DateDetailView):
    queryset = Post.objects.filter(published=True)
    month_format = '%m'
    date_field = 'date_url'

Use ArchiveIndexView to reduce code
Use ArchiveIndexView to reduce code

- from django.views.generic import ListView, MonthArchiveView, DateDetailView
+ from django.views.generic import ArchiveIndexView, MonthArchiveView, DateDetailView
  from django.shortcuts import get_object_or_404
- from django.utils import timezone
  from django.conf import settings
  from .models import Category, Post
  
  
- class PostListView(ListView):
+ class PostListView(ArchiveIndexView):
+     queryset = Post.objects.select_related().filter(published=True)
+     date_field = 'date'
      paginate_by = getattr(settings, 'NEWS_PER_PAGE', 10)
+     template_name_suffix = '_list'
+     context_object_name = 'object_list'
- 
-     def get_queryset(self):
-         return Post.objects.select_related().filter(
-                 published=True, date__lte=timezone.now())
  
  
- class PostListCategoryView(ListView):
+ class PostListCategoryView(PostListView):
-     paginate_by = getattr(settings, 'NEWS_PER_PAGE', 10)
      template_name_suffix = '_list_category'
  
      def get_queryset(self):
+         qs = super(PostListCategoryView, self).get_queryset()
          self.category = get_object_or_404(Category, slug=self.kwargs['slug'])
+         return qs.filter(category=self.category)
-         return Post.objects.select_related().filter(
-                 published=True,
-                 date__lte=timezone.now(),
-                 category=self.category)
  
      def get_context_data(self, **kwargs):
          context = super(PostListCategoryView, self).get_context_data(**kwargs)
          context['category'] = self.category
          return context
  
  
  class PostListMonthView(MonthArchiveView):
      queryset = Post.objects.filter(published=True)
      month_format = '%m'
      date_field = 'date_url'
  
  
  class PostDetailView(DateDetailView):
      queryset = Post.objects.filter(published=True)
      month_format = '%m'
      date_field = 'date_url'
  
Use ArchiveIndexView to reduce code
## Code Before:
from django.views.generic import ListView, MonthArchiveView, DateDetailView
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.conf import settings
from .models import Category, Post


class PostListView(ListView):
    paginate_by = getattr(settings, 'NEWS_PER_PAGE', 10)

    def get_queryset(self):
        return Post.objects.select_related().filter(
                published=True, date__lte=timezone.now())


class PostListCategoryView(ListView):
    paginate_by = getattr(settings, 'NEWS_PER_PAGE', 10)
    template_name_suffix = '_list_category'

    def get_queryset(self):
        self.category = get_object_or_404(Category, slug=self.kwargs['slug'])
        return Post.objects.select_related().filter(
                published=True,
                date__lte=timezone.now(),
                category=self.category)

    def get_context_data(self, **kwargs):
        context = super(PostListCategoryView, self).get_context_data(**kwargs)
        context['category'] = self.category
        return context


class PostListMonthView(MonthArchiveView):
    queryset = Post.objects.filter(published=True)
    month_format = '%m'
    date_field = 'date_url'


class PostDetailView(DateDetailView):
    queryset = Post.objects.filter(published=True)
    month_format = '%m'
    date_field = 'date_url'

## Instruction:
Use ArchiveIndexView to reduce code
## Code After:
from django.views.generic import ArchiveIndexView, MonthArchiveView, DateDetailView
from django.shortcuts import get_object_or_404
from django.conf import settings
from .models import Category, Post


class PostListView(ArchiveIndexView):
    queryset = Post.objects.select_related().filter(published=True)
    date_field = 'date'
    paginate_by = getattr(settings, 'NEWS_PER_PAGE', 10)
    template_name_suffix = '_list'
    context_object_name = 'object_list'


class PostListCategoryView(PostListView):
    template_name_suffix = '_list_category'

    def get_queryset(self):
        qs = super(PostListCategoryView, self).get_queryset()
        self.category = get_object_or_404(Category, slug=self.kwargs['slug'])
        return qs.filter(category=self.category)

    def get_context_data(self, **kwargs):
        context = super(PostListCategoryView, self).get_context_data(**kwargs)
        context['category'] = self.category
        return context


class PostListMonthView(MonthArchiveView):
    queryset = Post.objects.filter(published=True)
    month_format = '%m'
    date_field = 'date_url'


class PostDetailView(DateDetailView):
    queryset = Post.objects.filter(published=True)
    month_format = '%m'
    date_field = 'date_url'
