Django中不区分大小写的字段

3

目前,我有一个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'))

这个方法有效。然而,现在我有一个视图,想要显示所有事件的全名,在这里我想要显示原始名称。使用我的方法,这是不可能的(函数只能单向操作)。是否有更简洁的解决方案?

3个回答

3

这两个答案都严重依赖于应用程序后面的PostGres,因此我正在寻找更多独立于数据库的解决方案... - 5xum
2
那么也许你可以更新clean_full_name,但是不要返回清理后的字符串,而是执行验证并保持字符串不变?if MyModel.objects.filter(full_name__iexact=thestring).exists():raise ValidationError; return the_string - n__o

3

您可以添加另一个字段,它基本上是名称的短标识。实际上,我认为将名称作为唯一字段并不是一个好主意(但我应该澄清我不知道您的要求)。

基本上,短标识字段上的验证确保唯一性。此外,您可以将短标识字段从所有表单中隐藏,等等。

示例:

>>> 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 - 这确保了广泛用例的唯一性。

这不会解决重音字符的问题吗?但是当然,您可以在myfunction中进行验证,而不是另一个字段。我不明白您的困惑。 - karthikr
重点不在于有重音符号的字符。我已经知道要相等的字符串了。问题是如何在不破坏原始全名的情况下做到这一点... - 5xum
好的,这就是我建议使用单独的slug字段的原因,它可以让你保留原始的全名。基本上,slug是一个辅助字段,用于确保不良数据不会出现。我认为它并不能替代myfunction函数。我会让你再考虑一下这个问题。 - karthikr
啊,有一个误解。正如我之前所说:slugify是替换myfunction的函数,而不是slugfield本身。 - 5xum
哦...我只是在展示slugification的功能,以便明确观点(对不起没有表达清楚)。不过,我说的是模型层面上的SlugField - karthikr
显示剩余3条评论

0

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

您可以通过将验证代码放入属性设置器中来验证 full_name 字段。有关详细信息,请参阅此博客


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接