title: I want to add functionality in Quicksearch box to search using any data column not just name
body: <p>I want to quicksearch using any column name(like description, Status) current search is being performed using Name only</p>
  
  <p>class ApplicationList(APIView):
      permission_classes = (IsAuthenticated,)</p>
  
  <pre><code># parser_classes = (JSONParser,)
  
  def post(self, request, format=None):
      # Get a list of fields dynamically
      fields = list()
      for f in Application._meta.fields:
          if f.is_relation:
              continue
          fields.append(f.name)
  
      queryset = Application.objects_with_sprint_name.all()
  
      # Looking for a specific bubble?
      if 'bubble' in request.data:
          if request.data['bubble'] == '4-1':
              queryset = queryset.filter(assessment_phase__id=request.data['bubble']).exclude(attributes__contains={'application_disposition':'Removed'})
          else:
              queryset = queryset.filter(assessment_phase__id=request.data['bubble'])
  
      # Providing a search query?
      if 'search' in request.data:
          q_search = request.data['search']
  
          # Build the query
          q = get_query(q_search, fields)
          queryset = queryset.filter(q)
  
      if 'filter' in request.data:
          q = get_filter(request.data['filter'])
          if q:
              queryset = queryset.filter(q)
  
      page = int(request.data.get('page', 1))
      per_page = int(request.data.get('per_page', 25))
  
      # Sorting
      sort_by = request.data.get('sort_by', 'name') or 'name'
      sort_dir = request.data.get('sort_dir', 'asc') or 'asc'
  
      if sort_dir == 'desc':
          sort_dir = '-'
      else:
          sort_dir = ''
  
      # Is this an actual field or do we need to sort by the attributes__*?
      if sort_by not in fields:
          sort_by = 'attributes__' + sort_by
  
      queryset = queryset.order_by('{0}{1}'.format(sort_dir, sort_by))
  
      # Do a little data massaging
      untreated_data = queryset.values()
  
      data = list()
      for app in untreated_data:
          this_app = {}
          for k, v in app.items():
              if k == 'attributes':
                  continue
              if k == 'sprint_name':
                  this_app[k] = v
                  this_app['sprint'] = v
                  continue
  
              this_app[k] = v
          this_app.update(app['attributes'])
  
          data.append(this_app)
  
      start = (page-1) * per_page
      end = (page) * per_page
  
      response = {
          'total_rows': len(data),
          'data': data[start:end],
      }
      return Response(response)
  </code></pre>
  
  <p>def get_query(query_string, search_fields):
      ''' Returns a query, that is a combination of Q objects. That combination
          aims to search keywords within a model by testing the given search fields.</p>
  
  <pre><code>'''
  query = None  # Query to search for every search term
  terms = normalize_query(query_string)
  for term in terms:
      or_query = None  # Query to search for a given term in each field
      for field_name in search_fields:
          q = Q(**{"%s__icontains" % field_name: term})
          if or_query is None:
              or_query = q
          else:
              or_query = or_query | q
      if query is None:
          query = or_query
      else:
          query = query &amp; or_query
  return query
  </code></pre>
  
  <p>def get_filter(filter_dict):
      available_fields = [ field.name for field in Application._meta.fields ] \
                         + ApplicationManager.annotated_fields</p>
  
  <pre><code>query = None
  if filter_dict is None:
      return query
  
  for field_name, val in filter_dict.items():
      query_field = field_name
  
      # Quicksearch box
      if field_name == '_quicksearch_':
          q = Q(name__icontains=val)
  
          if query is None:
              query = q
          else:
              query = query &amp; q
  
          continue
  
      # Figure out if this field is part of the model
      # or in the attributes json field
      if query_field not in available_fields:
          query_field = 'attributes__{0}'.format(query_field)
  
      if isinstance(val, list):
          q = None
      #
      #     # Are we looking for null or blank?
          if '#is_null_or_blank#' in val:
              val.remove('#is_null_or_blank#')
              q = Q(**{"%s__isnull" % query_field: True}) | \
                  Q(**{query_field: ''}) | \
                  Q(**{query_field: []})
      #
      #     # Loop through the list and create some "OR" expressions
          for v in val:
              tmp = Q(**{"%s__contains" % query_field: v})
              if q is None:
                  q = tmp
              q = q | tmp
  
      elif val.startswith('#bool#'):
          bval = val[6:].lower() == 'true'
          q = Q(**{"%s" % query_field: bval})
      else:
          q = Q(**{"%s__icontains" % query_field: val})
  
      # # Add to our master query of all fields
      if query is None:
          query = q
      else:
          query = query &amp; q
  
  return query
  </code></pre>