Django中不区分大小写的字段

Posted

技术标签:

【中文标题】Django中不区分大小写的字段【英文标题】:Case insensitive field in Django 【发布时间】:2015-10-21 20:12:08 【问题描述】:

目前,我有一个 Django 项目,其中包含一个名为 Event 的模型,该模型具有多个属性,其中一个是 full_name

from django.db import models


class Event(models.Model):
    description = models.CharField(blank=False, max_length=200)
    full_name = models.CharField(blank=False, null=True, max_length=200, unique=True)

我想要实现的是防止用户进行两个事件,其中一个被称为MyEvent,另一个被称为myevent,所以我希望名称不区分大小写。此外,我来自一个带有一些有趣字母的国家,例如š。用户已经习惯了不支持这些字母的计算机系统,所以我还想阻止两个事件的存在,一个叫šoo,另一个叫soo

基本上,我有一个函数 myfunction 并希望有一个模型约束,这样对于模型的每个实例,值 myfunction(instance.full_name) 都是唯一的。

我的第一个想法,哪种工作,是有一个具有干净全名函数的模型表单:

def clean_full_name(self):
    return myfunction(self.cleaned_data.get('full_name'))

这行得通。但是,我现在有一个视图,我想在其中显示所有事件的全名,在这里,我想显示原始名称。使用我的方法,这是不可能的(该功能仅是单向的)。有没有优雅的解决方案?

【问题讨论】:

【参考方案1】:

您可以拥有另一个字段,它基本上是名称的 slug。事实上,我认为将name 作为一个独特的字段并不是一个好主意(但我应该澄清一下,我不知道您的要求)。

基本上,在slug field ensures uniqueness 上进行验证。此外,您可以将 slug 字段隐藏在所有表单等中。

例子:

>>> from django.utils.text import slugify
>>> slugify(u"śtack Overflow")
u'stack-overflow'
>>> slugify(u"stack Overflow")
u'stack-overflow'
>>> slugify(u"stack  Overflow")
u'stack-overflow'
>>> slugify(u"stack \t Overflow")
u'stack-overflow'
>>> slugify(u"stack \n Overflow")
u'stack-overflow'

其中一些组合映射到同一个 slug - 这确保了广泛用例的唯一性。

【讨论】:

据我了解,这个slugify 只是myfunction 的替代品,所以我看不出这如何回答我的问题... 这不能解决重音字符的问题吗?但可以肯定的是,您可以在 myfunction 而不是其他字段中进行验证。我不明白你的困惑 重音字符不是问题。我已经知道要等同于哪些字符串。问题是如何在不破坏原始全名的情况下做到这一点... 嗯,这就是我推荐一个单独的 slug 字段的原因,它可以让你保留原来的全名。基本上,slug 是一个辅助字段,以确保不会出现不良数据。我不认为它是 myfunction 的替代品。我会让你多考虑一下。 啊,误会了。正如我之前所说:slugifymyfunction 的替代品。不是蛞蝓场本身【参考方案2】:

一个想法是在字段上实现不区分大小写的唯一约束。

可能的答案:

Case insensitive unique model fields in Django? Unique model field in Django and case sensitivity (postgres)

【讨论】:

这两个答案都严重依赖应用程序背后的 PostGres,所以我正在寻找一个更加独立于数据库的解决方案...... 那么也许您可以更新 clean_full_name,但是,不是返回清理后的字符串,而是执行验证并保持字符串不变? if MyModel.objects.filter(full_name__iexact=thestring).exists():raise ValidationError; return the_string?【参考方案3】:

只需将 full_name 和 clean_full_name 都保存在数据库中,并使 clean_full_name 唯一。

您可以通过将验证代码放入属性设置器中来验证 full_name 字段。详情请查看this blog。

【讨论】:

但是我在哪里运行验证?我的意思是,EventForm 是否有一个 clean_full_name_unique 字段?但我希望它自动填充。如果给定非唯一名称,表单将无法正确响应... @5xum 您可以将模型中的 clean_full_name 设置为不可编辑、唯一并覆盖模型的保存方法以自动填充它。然后编辑模型的验证以从 clean_full_name 捕获验证错误并将其传递给 full_name。编辑:如果您仅将 clean_full_name 用于验证/识别目的,我不会覆盖属性设置器。 @PiotrJaszkowski “从 clean_full_name 捕获验证错误并将其传递给 full_name”是什么意思?这怎么可能?

以上是关于Django中不区分大小写的字段的主要内容,如果未能解决你的问题,请参考以下文章

如何实现 Django 不区分大小写的模型字段?

Django 中的唯一模型字段和区分大小写(postgres)

Django 中的唯一模型字段和区分大小写(postgres)

django orm总结--解决查询结果不区分大小写问题

如何使用 Django 模型进行不区分大小写的查询

Oracle中不区分大小写的主键