Django LowerCaseCharField

Can*_*gir 12 python django lowercase

我们实现了LowerCaseCharField.我们很乐意听到更好的实施建议.

from django.db.models.fields import CharField

class LowerCaseCharField(CharField):
    """
    Defines a charfield which automatically converts all inputs to
    lowercase and saves.
    """

    def pre_save(self, model_instance, add):
        """
        Converts the string to lowercase before saving.
        """
        current_value = getattr(model_instance, self.attname)
        setattr(model_instance, self.attname, current_value.lower())
        return getattr(model_instance, self.attname)
Run Code Online (Sandbox Code Playgroud)

事实上我们喜欢的是:

> modelinstance.field_name="TEST"
> print modelinstance.field_name
'test'
Run Code Online (Sandbox Code Playgroud)

当前实现仅在保存时转换为小写.

Wil*_*rdy 16

您可能希望覆盖to_python,这将允许您在执行数据库查找时比较非小写字符串.实际的方法是get_prep_value,但正如所要求to_python的那样CharField,覆盖它更方便:

def to_python(self, value):
    value = super(LowerCaseCharField, self).to_python(value)
    if isinstance(value, basestring):
        return value.lower()
    return value
Run Code Online (Sandbox Code Playgroud)

现在您可以执行以下查询:

MyModel.objects.filter(lccf="MiXeD")
Run Code Online (Sandbox Code Playgroud)

编辑:

重读您的问题,看起来您希望降低立即生效.要做到这一点,你需要创建一个描述符(带有新式的Python对象__get____set__方法,请参阅Python文档和相关模型Django的代码),并覆盖contribute_to_class在现场模特的字段设置为你的描述符.

这是我头顶的完整示例,对于想要修改设置值的所有字段,该示例应该是可重用的.

class ModifyingFieldDescriptor(object):
    """ Modifies a field when set using the field's (overriden) .to_python() method. """
    def __init__(self, field):  
        self.field = field  
    def __get__(self, instance, owner=None):
        if instance is None:
            raise AttributeError('Can only be accessed via an instance.')  
        return instance.__dict__[self.field.name]
    def __set__(self, instance, value):
        instance.__dict__[self.field.name] = self.field.to_python(value)

class LowerCaseCharField(CharField):
    def to_python(self, value):
        value = super(LowerCaseCharField, self).to_python(value)
        if isinstance(value, basestring):
            return value.lower()
        return value
    def contribute_to_class(self, cls, name):
        super(LowerCaseCharField, self).contribute_to_class(cls, name)
        setattr(cls, self.name, ModifyingFieldDescriptor(self))
Run Code Online (Sandbox Code Playgroud)