code: def search(self, q, language=None, current_site_only=True):
          
          from cms.plugin_pool import plugin_pool
  
          qs = self.get_queryset()
          qs = qs.public()
  
          if current_site_only:
              site = Site.objects.get_current()
              qs = qs.filter(tree__site=site)
  
          qt = Q(title_set__title__icontains=q)
  
          # find 'searchable' plugins and build query
          qp = Q()
          plugins = plugin_pool.get_all_plugins()
          for plugin in plugins:
              cmsplugin = plugin.model
              if not (
                  hasattr(cmsplugin, 'search_fields') and
                  hasattr(cmsplugin, 'cmsplugin_ptr')
              ):
                  continue
              field = cmsplugin.cmsplugin_ptr.field
              related_query_name = field.related_query_name()
              if related_query_name and not related_query_name.startswith('+'):
                  for field in cmsplugin.search_fields:
                      qp |= Q(**{
                          'placeholders__cmsplugin__{0}__{1}__icontains'.format(
                              related_query_name,
                              field,
                          ): q})
          if language:
              qt &= Q(title_set__language=language)
              qp &= Q(cmsplugin__language=language)
  
          qs = qs.filter(qt | qp)
  
          return qs.distinct()
docs: Simple search function
  
          Plugins can define a 'search_fields' tuple similar to ModelAdmin classes