title: Creating a Gin Index with Trigram (gin_trgm_ops) in Django model
body: <p>The new TrigramSimilarity feature of the django.contrib.postgres was great for a problem I had. I use it for a search bar to find hard to spell latin names. The problem is that there are over 2 million names, and the search takes longer then I want.</p>
  <p>I'd like to create a index on the trigrams as descibed in the <a href="https://www.postgresql.org/docs/9.6/static/pgtrgm.html" rel="nofollow noreferrer">postgres documentation</a>.</p>
  <p>But I am not sure how to do this in a way that the Django API would make use of it. For the postgres text search there is a description on how to create an index, but not for the <a href="https://docs.djangoproject.com/en/dev/ref/contrib/postgres/search/#trigram-similarity" rel="nofollow noreferrer">trigram similarity</a>.</p>
  <p>This is what I have right now:</p>
  <pre class="lang-python prettyprint-override"><code>class NCBI_names(models.Model):
      tax_id          =   models.ForeignKey(NCBI_nodes, on_delete=models.CASCADE, default = 0)
      name_txt        =   models.CharField(max_length=255, default = '')
      name_class      =   models.CharField(max_length=32, db_index=True, default = '')
  
      class Meta:
          indexes = [GinIndex(fields=['name_txt'])]
  </code></pre>
  <p>In the view's <code>get_queryset</code> method:</p>
  <pre class="lang-python prettyprint-override"><code>class TaxonSearchListView(ListView):    
      #form_class=TaxonSearchForm
      template_name='collectie/taxon_list.html'
      paginate_by=20
      model=NCBI_names
      context_object_name = 'taxon_list'
  
      def dispatch(self, request, *args, **kwargs):
          query = request.GET.get('q')
          if query:
              try:
                  tax_id = self.model.objects.get(name_txt__iexact=query).tax_id.tax_id
                  return redirect('collectie:taxon_detail', tax_id)
              except (self.model.DoesNotExist, self.model.MultipleObjectsReturned) as e:
                  return super(TaxonSearchListView, self).dispatch(request, *args, **kwargs)
          else:
              return super(TaxonSearchListView, self).dispatch(request, *args, **kwargs)
      
      def get_queryset(self):
          result = super(TaxonSearchListView, self).get_queryset()
          #
          query = self.request.GET.get('q')
          if query:            
              result = result.exclude(name_txt__icontains = 'sp.')
              result = result.annotate(similarity=TrigramSimilarity('name_txt', query)).filter(similarity__gt=0.3).order_by('-similarity')
          return result
  </code></pre>