text: from __future__ import unicode_literals
  
  from email.header import Header
  
  import django
  from django.core.exceptions import ImproperlyConfigured
  from django.http import HttpResponse
  from django.views.generic.list import BaseListView, MultipleObjectMixin
  
  from .utils import ColumnSerializer
  
  
  def encode_header(value):
      return Header(value, 'utf-8').encode()
  
  
  class CsvResponse(HttpResponse):
      def __init__(self, filename, content_type='text/csv', **kwargs):
          super(CsvResponse, self).__init__(content_type=content_type, **kwargs)
          disposition = 'attachment; filename="{0}"'.format(filename)
          # BBB: Django 1.4 and earlier didn't support non-ASCII headers.  Later
          # versions do this for us.
          if django.VERSION < (1, 5):
              disposition = encode_header(disposition)
          self['Content-Disposition'] = disposition
  
  
  class CsvResponseMixin(MultipleObjectMixin):
      """
      A ListView mixin that returns a CsvResponse.
      """
      response_class = CsvResponse
      column_serializer_class = ColumnSerializer
      columns = None
      output_headers = True
      filename = '{model_name}_list.csv'
  
      def render_to_response(self, context, **kwargs):
          queryset = context['object_list']
          model = queryset.model
          response = self.response_class(
              filename=self.get_filename(model),
          )
          serialize = self.get_column_serializer(model)
          serialize(queryset, file=response)
          return response
  
      def get_column_serializer_class(self, model):
          return self.column_serializer_class
  
      def get_column_serializer(self, model):
          return self.get_column_serializer_class(model)(
              self.get_columns(model),
              output_headers=self.output_headers,
          )
  
      def get_columns(self, model):
          if self.columns is None:
              raise ImproperlyConfigured('Please set the columns.')
          return self.columns
  
      def get_filename(self, model):
          opts = model._meta
          try:
              model_name = opts.model_name
          except AttributeError:
              # for Django < 1.6. Deprecated in 1.6 & removed in 1.8.
              model_name = opts.module_name
          return self.filename.format(
              model_name=model_name,
          )
  
  
  class CsvView(CsvResponseMixin, BaseListView):
      """
      A ListView that returns a CsvResponse.
      """
  