Ich hätte gerne ein CharField mit fester Länge in meinem Modell. Mit anderen Worten, ich möchte, dass nur eine bestimmte Länge gültig ist.
Ich habe versucht so etwas zu tun
volumenumber = models.CharField('Volume Number', max_length=4, min_length=4)
aber es gibt mir einen Fehler (es scheint, dass ich sowohl max_length als auch min_length gleichzeitig verwenden kann).
Gibt es einen anderen schnellen Weg?
Vielen Dank
BEARBEITEN:
Nach den Vorschlägen einiger Leute werde ich etwas genauer sein:
Mein Modell ist das:
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))
Was ich will ist, dass das volumenumber
genau 4 Zeichen sein muss.
IE, wenn jemand '4b' Django einfügt, gibt einen Fehler aus, weil er eine Zeichenfolge von 4 Zeichen erwartet.
Also habe ich es mit versucht
volumenumber = models.CharField('Volume Number', max_length=4, min_length=4)
aber es gibt mir diesen Fehler:
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'
Das erscheint natürlich nicht, wenn ich nur "max_length" ODER "min_length" verwende.
Ich habe die Dokumentation auf der Django-Website gelesen und es scheint, dass ich Recht habe (ich kann nicht beide zusammen verwenden), also frage ich, ob es einen anderen Weg gibt, das Problem zu lösen.
Danke noch einmal
quelle
Sie müssen nicht einmal eine benutzerdefinierte schreiben. Verwenden Sie einfach das,
RegexValidator
was Django liefert.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')])
Aus den Django Docs:
class RegexValidator(\[regex=None, message=None, code=None\])
regex
: Ein gültiger regulärer Ausdruck, der übereinstimmt. Weitere Informationen zu Regex in Python finden Sie in diesem hervorragenden HowTo: http://docs.python.org/howto/regex.htmlmessage
: Die Nachricht wird im Fehlerfall an den Benutzer zurückgegeben.code
: Von ValidationError zurückgegebener Fehlercode. Für Ihren Anwendungsfall nicht wichtig, können Sie ihn weglassen.Achtung, der von mir vorgeschlagene reguläre Ausdruck erlaubt alle Zeichen, einschließlich Leerzeichen. Um nur alphanumerische Zeichen zuzulassen, ersetzen Sie das '.' mit '\ w' im Regex-Argument. Für andere Anforderungen ReadTheDocs;).
quelle
Ähnlich wie oben, aber für das, was es wert ist, können Sie auch mit MinLengthValidator fortfahren, den Django liefert. Hat für mich gearbeitet. Der Code würde ungefähr so aussehen:
from django.core.validators import MinLengthValidator ... class Volume(models.Model): volumenumber = models.CharField('Volume Number', max_length=4, validators=[MinLengthValidator(4)]) ...
quelle
Sie können einen benutzerdefinierten Validator schreiben, wie von @Ben vorgeschlagen. Zum Datum dieser Antwort finden Sie die entsprechenden Anweisungen unter https://docs.djangoproject.com/de/dev/ref/validators/.
Der Code wäre ungefähr so (Kopieren vom Link):
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])
quelle
from django.core.validators import MinLengthValidator
Noch eine Implementierung unter Verwendung eines benutzerdefinierten Modellfelds :
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
quelle