Добавление поля с нормализованным именем было бы разумным решением, хотя я бы заполнил его, переписав .save()
на модели Product
.
class Product(models.Model):
name = models.CharField(max_length=5)
normalized_name = models.CharField(max_length=5)
def save(self, *args, **kwargs):
self.normalized_name = self.normalize_name(name)
super().save(*args, **kwargs)
@classmethod
def normalize_name(cls, name):
return name.replace('-', '') # Maybe also remove spaces?
Product.objects.filter(normalized_name=Product.normalize_name('A-123'))
Product.objects.filter(normalized_name=Product.normalize_name('A123'))
Если вы используете это более чем в одном место, вы можете захотеть создать собственный менеджер, чтобы избежать дублирования кода:
class ProductManager(models.Manager):
def filter_by_normalized_name(name):
normalized_name = Product.normalize_name('A-123')
return self.get_queryset().filter(normalized_name=normalized_name)
class Product(models.Model):
...
objects = ProductManager
Product.objects.filter_by_normalized_name('A123')
Product.objects.filter_by_normalized_name('A-123')
В качестве альтернативы, если Product.name
всегда имеет одинаковую структуру, вы можете просто нормализовать ваш поисковый запрос.
Например, если вы знаете, что имя всегда содержит дефис в качестве второго символа:
if search_term[1] != '-':
search_term = f"{search_term[0]}-{search_term[1:]}"
Для более сложного решения вам может потребоваться поиск в полнотекстовом поиске с помощью PostgreSQL или ElasticSearch.