Почему max_length игнорируется в BinaryField? - PullRequest
0 голосов
/ 05 марта 2020

Я пытаюсь создать систему приглашений для регистрации пользователей, в которой хранится хэш-сумма md5 на основе идентификатора объекта. Вот как определяется моя модель:

class Invite(TimestampedModel):
    user = models.ForeignKey(User, default=None, null=True, blank=True, on_delete=models.CASCADE)
    _code = models.BinaryField(max_length=16, unique=True)

    @classmethod
    def create(cls):
        invite = cls.objects.create()

        hash_obj = hashlib.md5()
        hash_obj.update(str(invite.id).encode('utf-8'))
        invite._code = hash_obj.digest()

        invite.save()
        return invite

Таким образом, когда я вызываю Invite.create(), я вижу в базе данных строку с _code длиной 16 символов (например, ��#�"��Zo�n�%��V).

Проблема возникает, однако, когда я настраиваю max_length на 2. Я ожидал, что Django либо выдаст ошибку, либо усечет значение до двух байтов, но этого не произошло; Я все еще вижу 16 байтов в новых строках. Да, я управлял makemigrations и migrate.

Что здесь происходит? Это немного о том, что я не могу ограничить длину вообще. Я предполагаю, что по умолчанию 50, но я понятия не имею, почему. Любые мысли приветствуются.

Описание BinaryField здесь.

1 Ответ

0 голосов
/ 06 марта 2020

Если вы посмотрите на исходный код класса BinaryField, вы увидите, что параметр max_length добавит только валидатор в поле:

class BinaryField(Field):
    description = _("Raw binary data")
    empty_values = [None, b'']

def __init__(self, *args, **kwargs):
        kwargs.setdefault('editable', False)
        super().__init__(*args, **kwargs)
        if self.max_length is not None:
            self.validators.append(validators.MaxLengthValidator(self.max_length))

Теперь вы go к документы и поиск способов запуска валидаторов:

Обратите внимание, что валидаторы не будут запускаться автоматически при сохранении модели, но если вы используете ModelForm, он будет запускать валидаторы в любых полях, которые включается в вашу форму.

Теперь вы видите, что если вы не используете ModelForm, вам придется самостоятельно выполнять проверки:

Есть три шаги по проверке модели:

Проверка полей модели - Model.clean_fields ()

Проверка модели в целом - Model.clean ()

Проверка поля уникальность - Model.validate_unique ()

Все три шага выполняются при вызове метода full_clean () модели. Когда вы используете ModelForm, вызов is_valid () будет выполнять эти шаги проверки для всех полей, которые включены в форму. См. Документацию ModelForm для получения дополнительной информации.

Вы должны вызывать метод full_clean () модели только в том случае, если вы планируете самостоятельно обрабатывать ошибки проверки или если вы исключили из ModelForm поля, требующие проверки.

Итак Как я уже сказал, это не имеет ничего общего с миграциями, вам просто нужно вызвать метод full_clean (или просто clean_fields one) или использовать ModelForm и вызвать метод is_valid().

refs :

Реализация BinaryField

Как работают валидаторы

Проверка моделей

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...