Django: CharField с фиксированной длиной, как?
Мне нравилось иметь в моей модели CharField с фиксированной длиной. Другими словами, я хочу, чтобы была действительна только указанная длина.
Я попытался сделать что-то вроде
volumenumber = models.CharField('Volume Number', max_length=4, min_length=4)
но это дает мне ошибку (кажется, что я могу одновременно использовать как max_length, так и min_length).
Есть ли еще один быстрый способ?
Спасибо
EDIT:
Следуя предложениям некоторых людей, я буду более конкретным:
Моя модель такова:
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, и кажется, что я прав (я не могу использовать оба вместе), поэтому я спрашиваю, есть ли другой способ решить проблему.
Еще раз спасибо
Ответы
Ответ 1
У экземпляров полей базы данных CharField только параметр max_length
, как указано в docs. Вероятно, это связано с тем, что в SQL существует только эквивалент ограничения длины символа.
Объекты Field 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)
Ответ 2
Вам даже не нужно писать пользовательский. Просто используйте RegexValidator
, который поставляется Django.
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 Docs: class RegexValidator(\[regex=None, message=None, code=None\])
regex
: действительное регулярное выражение для соответствия. Для получения дополнительной информации о регулярном выражении в Python проверьте этот отличный HowTo:
http://docs.python.org/howto/regex.html
message
: сообщение возвращается пользователю в случае сбоя.
code
: код ошибки, возвращаемый ValidationError. Не важно для вашего случая использования, вы можете оставить его.
Остерегайтесь, предлагаемое мной регулярное выражение позволит любым символам, включая пробелы. Чтобы разрешить только буквенно-цифровые символы, замените '.' с '\ w' в аргументе regex. Для других требований, ReadTheDocs;).
Ответ 3
Вид по тем же линиям, что и выше, но за то, что он стоит, можно также пойти с MinLengthValidator, который поставляется django. Работал для меня. Код будет выглядеть примерно так:
from django.core.validators import MinLengthValidator
...
class Volume(models.Model):
volumenumber = models.CharField('Volume Number', max_length=4, validators=[MinLengthValidator(4)])
...
Ответ 4
Вы можете написать собственный валидатор, как это предложено @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])