from django.core.exceptions import ImproperlyConfigured
from django.views.generic import ListView

class ListFilteredMixin(object):
    """
    Mixin that adds support for django-filter
    """

    filter_set = None
    
    def get_filter_set(self):
        if self.filter_set:
            return self.filter_set
        else:
            raise ImproperlyConfigured(
                "ListFilterMixin requires either a definition of "
                "'filter_set' or an implementation of 'get_filter()'")

    def get_base_queryset(self):
        """
        We can decided to either alter the queryset before or after applying the
        FilterSet
        """
        return super(ListFilteredMixin, self).get_queryset()

    def get_constructed_filter(self):
        # We need to store the instantiated FilterSet cause we use it in
        # get_queryset and in get_context_data
        if getattr(self, 'constructed_filter', None):
            return self.constructed_filter
        else:
            f = self.get_filter_set()(self.get_filter_data(),
                                      queryset=self.get_base_queryset())
            self.constructed_filter = f
            return f
    
    def get_filter_data(self):
        """
        This method returns filter parameters stored in GET request.
        """
        return self.request.GET

    def get_queryset(self):
        return self.get_constructed_filter().qs

    def get_context_data(self, **kwargs):
        kwargs.update({
            'filter': self.get_constructed_filter(),
            'filter_exists': True,
        })
        return super(ListFilteredMixin, self).get_context_data(**kwargs)


class ListFilteredView(ListFilteredMixin, ListView):
    """
    A list view that can be filtered by django-filter
    """
