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 的替代品。我会让你多考虑一下。
啊,误会了。正如我之前所说:slugify
是myfunction
的替代品。不是蛞蝓场本身【参考方案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 中的唯一模型字段和区分大小写(postgres)