我希望在我的模型中有一个固定长度的CharField。换句话说,我希望只有指定的长度才有效。
我尝试做类似
的事情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个字符的字符串。
所以我尝试了
volumenumber = models.CharField('Volume Number', max_length=4, min_length=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'
如果我只使用“max_length”或“min_length”,那显然不会出现。
我阅读了django网站上的文档,似乎我是对的(我不能同时使用它们),所以我问是否有其他方法可以解决问题。
再次感谢
答案 0 :(得分:77)
你甚至不必写自定义的。只需使用Django提供的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中正则表达式的更多信息,请查看此优秀的HowTo:
http://docs.python.org/howto/regex.html
message
:如果失败,将返回给用户。
code
:ValidationError返回的错误代码。对于您的使用案例并不重要,您可以将其删除。
注意,我建议的正则表达式将允许任何字符,包括空格。要仅允许使用字母数字字符,请替换“。”在正则表达式参数中使用'\ w'。对于其他要求,ReadTheDocs;)。
答案 1 :(得分:55)
与上述相同,但是对于它的价值,你也可以继续使用django提供的MinLengthValidator。为我工作。代码看起来像这样:
from django.core.validators import MinLengthValidator
...
class Volume(models.Model):
volumenumber = models.CharField('Volume Number', max_length=4, validators=[MinLengthValidator(4)])
...
答案 2 :(得分:39)
CharField数据库模型字段实例只有max_length
参数,如docs中所示。这可能是因为SQL中只有最大字符长度约束。
Form Field CharField个对象确实有min_length
个参数。因此,您必须为此特定模型编写自定义ModelForm,并使用自定义模型覆盖默认管理模型表单。
类似的东西:
# 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)
答案 3 :(得分:16)
您可以按@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_length])
答案 4 :(得分:0)
使用custom model field的另一种实现方式:
from django.core.validators import BaseValidator
from django.db import models
from django.utils.deconstruct import deconstructible
@deconstructible
class FixedLengthValidator(BaseValidator):
message = 'Ensure this value has %(limit_value)d character (it has %(show_value)d).'
code = 'length'
def compare(self, a, b):
return a != b
def clean(self, x):
return len(x)
class FixedLengthCharField(models.CharField):
def __init__(self, *args, length, **kwargs):
self.length = length
kwargs['max_length'] = length
super().__init__(*args, **kwargs)
self.validators.insert(0, FixedLengthValidator(length))
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
del kwargs['max_length']
kwargs['length'] = self.length
return name, path, args, kwargs