代码之家  ›  专栏  ›  技术社区  ›  Giovanni Di Milia

Django:charfield,固定长度,如何?

  •  53
  • Giovanni Di Milia  · 技术社区  · 14 年前

    我想在我的模型中有一个固定长度的字符场。换句话说,我希望只有指定的长度是有效的。

    我试着做一些像

    volumenumber = models.CharField('Volume Number', max_length=4, min_length=4)
    

    但它给了我一个错误(看起来我可以同时使用max-length和min-length)。

    还有别的捷径吗?

    谢谢

    编辑:

    根据一些人的建议,我会更具体一点:

    我的模型是:

    class Volume(models.Model):
        vid = models.AutoField(primary_key=True)
        jid = models.ForeignKey(Journals, db_column='jid', null=True, verbose_name = "Journal")
        volumenumber = models.CharField('Volume Number')
        date_publication = models.CharField('Date of Publication', max_length=6, blank=True)
        class Meta:
            db_table = u'volume'
            verbose_name = "Volume"
            ordering = ['jid', 'volumenumber']
            unique_together = ('jid', 'volumenumber')
        def __unicode__(self):
            return (str(self.jid) + ' - ' + str(self.volumenumber))
    

    我想要的是 volumenumber 必须正好是4个字符。

    即。 如果有人插入“4b”,Django会出错,因为它需要4个字符的字符串。

    所以我尝试了

    volume number=models.charfield('卷号,最大长度=4,最小长度=4)
    

    但它给了我这个错误:

    Validating models...
    Unhandled exception in thread started by <function inner_run at 0x70feb0>
    Traceback (most recent call last):
      File "/Library/Python/2.5/site-packages/django/core/management/commands/runserver.py", line 48, in inner_run
        self.validate(display_num_errors=True)
      File "/Library/Python/2.5/site-packages/django/core/management/base.py", line 249, in validate
        num_errors = get_validation_errors(s, app)
      File "/Library/Python/2.5/site-packages/django/core/management/validation.py", line 28, in get_validation_errors
        for (app_name, error) in get_app_errors().items():
      File "/Library/Python/2.5/site-packages/django/db/models/loading.py", line 131, in get_app_errors
        self._populate()
      File "/Library/Python/2.5/site-packages/django/db/models/loading.py", line 58, in _populate
        self.load_app(app_name, True)
      File "/Library/Python/2.5/site-packages/django/db/models/loading.py", line 74, in load_app
        models = import_module('.models', app_name)
      File "/Library/Python/2.5/site-packages/django/utils/importlib.py", line 35, in import_module
        __import__(name)
      File "/Users/Giovanni/src/djangoTestSite/../djangoTestSite/journaldb/models.py", line 120, in <module>
        class Volume(models.Model):
      File "/Users/Giovanni/src/djangoTestSite/../djangoTestSite/journaldb/models.py", line 123, in Volume
        volumenumber = models.CharField('Volume Number', max_length=4, min_length=4)
    TypeError: __init__() got an unexpected keyword argument 'min_length'
    

    如果我只使用“最大长度”或“最小长度”,这显然不会出现。

    我阅读了Django网站上的文档,似乎我是对的(我不能同时使用两者),所以我在问是否有其他方法来解决这个问题。

    再次感谢

    4 回复  |  直到 7 年前
        1
  •  38
  •   Haes    14 年前

    charfield数据库模型字段实例只有 max_length 参数,如 docs . 这可能是因为在SQL中只有一个max character length约束等价物。

    Form Field CharField 另一方面,对象确实具有 min_length 参数。因此,您必须为此特定模型编写自定义模型窗体,并用自定义模型窗体覆盖默认的管理模型窗体。

    就像这样:

    # admin.py
    
    from django import forms
    
    ...
    
    class VolumeForm(forms.ModelForm):
        volumenumber = forms.CharField(max_length=4, min_length=4)
    
        class Meta:
            model = Volume
    
    
    class VolumeAdmin(admin.ModelAdmin):
        form = VolumeForm
    
    ...
    
    admin.site.register(Volume, VolumeAdmin)
    
        2
  •  76
  •   Alasdair    7 年前

    你甚至不用写定制的。只使用 RegexValidator 是姜戈提供的。

    from django.core.validators import RegexValidator
    
    class MyModel(models.Model):
        myfield = models.CharField(validators=[RegexValidator(regex='^.{4}$', message='Length has to be 4', code='nomatch')])
    

    来自Django文档: class RegexValidator(\[regex=None, message=None, code=None\])

    regex :要匹配的有效正则表达式。有关python中regex的更多信息,请查看以下优秀的操作方法: http://docs.python.org/howto/regex.html

    message :失败时返回给用户的消息。

    code :validationError返回错误代码。对于您的使用案例不重要,您可以忽略它。

    当心,我建议的regex将允许任何字符,包括空格。要只允许字母数字字符,请在regex参数中用'\w'替换'.'。对于其他要求,请阅读docs;)。

        3
  •  48
  •   Chetan    9 年前

    有点像上面所说的那样,但是为了它的价值,你也可以继续使用Django提供的MinlengthValidator。为我工作。代码如下所示:

    from django.core.validators import MinLengthValidator
    ...
    class Volume(models.Model):
    volumenumber = models.CharField('Volume Number', max_length=4, validators=[MinLengthValidator(4)])
    ...
    
        4
  •  16
  •   tjb    12 年前

    您可以按照@ben的建议编写自定义验证器。自本回答之日起,有关执行此操作的说明,请访问 https://docs.djangoproject.com/en/dev/ref/validators/

    代码如下(从链接复制):

    from django.core.exceptions import ValidationError
    
    def validate_length(value,length=6):
        if len(str(value))!=length:
            raise ValidationError(u'%s is not the correct length' % value)
    
    from django.db import models
    
    class MyModel(models.Model):
        constraint_length_charField = models.CharField(validators=[validate_validate_length])