Answer the question
In order to leave comments, you need to log in
How to bring full text search to mind in Djnago + PostgreSQL?
There is a full text search implemented using "django.contrib.postgres". Handled in Views like this:
class search(ListView):
model = Product
paginate_by = 14
template_name = 'catalog/product_list.html'
def get_queryset(self):
stop_words = ~SearchQuery(['и', 'при', 'а', 'для', 'в', 'на', 'из', 'которые', 'дешовый', 'специальные', 'недорогие', 'по', 'у', 'за'])
queryset = super(search, self).get_queryset()
q = self.request.GET.get("q")
if q:
return queryset.annotate(search=SearchVector('brand__name', 'name', 'category__name', 'categorysub__name')).order_by('price').filter(search=q)
return queryset.annotate(search=SearchVector('brand__name', 'name', 'category__name', 'categorysub__name')).order_by('price').filter(search=stop_words))
elif not q:
return queryset.order_by('price')
class Product(models.Model):
category = models.ForeignKey(Category, related_name='products', verbose_name="Категория")
categorysub = models.ForeignKey(SubCategory, null=True, blank=True, verbose_name="Подкатегория")
name = models.CharField(max_length=100, db_index=True, verbose_name="Название")
slug = models.SlugField(max_length=100, db_index=True, verbose_name="Псевдоним")
image = models.ImageField(upload_to='static/products/%Y/%m/%d/', blank=True, verbose_name="Изображение товара")
description = models.TextField(blank=True, verbose_name="Описание")
brand = models.ForeignKey(Brand, related_name='products', null=True, verbose_name="Бренд")
price = models.DecimalField(max_digits=10, decimal_places=0, verbose_name="Цена")
stock = models.PositiveIntegerField(verbose_name="На складе")
available = models.BooleanField(default=True, verbose_name="Доступен")
created = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания")
updated = models.DateTimeField(auto_now=True, verbose_name="Дата обновления")
class Meta:
verbose_name = 'Продукт'
verbose_name_plural = 'Продукты'
ordering = ['name']
index_together = [
['id', 'slug']
]
def __str__(self):
return self.name
Answer the question
In order to leave comments, you need to log in
Since no one answers, I will answer myself.
In PostgreSQL we activate the "pg_trgm" extension:
Then in Views we import:
And in request processing we use this logic:
vector = SearchVector('categorysub__name', 'brand__name', 'category__name', 'name', raw=True, fields=('name'))
vector_trgm = TrigramSimilarity('categorysub__name', q, raw=True, fields=('name')) + TrigramSimilarity('brand__name', q, raw=True, fields=('name')) + TrigramSimilarity('category__name', q, raw=True, fields=('name')) + TrigramSimilarity('name', q, raw=True, fields=('name'))
return queryset.annotate(search=vector).order_by('price').filter(search=q) or queryset.annotate(similarity=vector_trgm).filter(similarity__gt=0.2).order_by('price')
TrigramSimilarity
without , SearchVector,
then the search result will not always be true.
And in SearchVector there are no raw & fields arguments where are they used?
And there will be this error __init__() got an unexpected keyword argument 'raw' (
I redid it a bit for 2021). And their requirements and earned!
Thank you very much for posting the answer to this question.
Thank you.
And the question is where did you find the info? To this question. In the off dock it is there but not in combination.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question