python - Django:有没有办法过滤模型并忽略存储的连字符?

标签 python django

我有一个这样的模型:

class Product(models.Model):
   name = models.CharField(max_length=5)

名称示例:A-123

是否有办法过滤此名称字段,以便我可以输入连字符或将其省略,并获得相同的结果?例如,查询“A-123”和“A123”将返回相同的项目。使用常规过滤器,我仅在执行“A-123”时得到结果。

如果不是,最好的解决方案是制作一个 on_save 触发器来填充辅助“可搜索”字段吗?

这将是我最初的想法,但我担心这会效率低下。

我考虑过的另一种方法是拉出所有对象,然后循环并删除连字符以找到匹配项,但我再次担心性能问题/效率。

最佳答案

添加具有规范化名称的字段将是一个明智的解决方案,尽管我会通过覆盖 Product 模型上的 .save() 来填充它。

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 的全文搜索。

关于python - Django:有没有办法过滤模型并忽略存储的连字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59684315/

相关文章:

python - 如何使用循环重写二维数组切片(打开cv格式)

django - 对象没有属性 - HyperlinkedRelatedField

python - 如何在 Telegram 上根据文件 ID 发送文件

python - 类型错误 : can only concatenate str (not "numpy.int64") to str while trying to plot the graph tree

python - 使用 clean() 对带有下划线的字段进行 ModelForm 验证

django - 如何使用相同的 django 表单编辑/添加对象?

python - Django 管理员。显示分层下拉过滤器

Django:默认语言 i18n

python - 将 hlines 和 vlines 捕捉到 matplotlib 中的整个像素

python - 如何获取特定日期之前发布的 python 包的版本号列表?