Подтвердить что ты не робот

Автоматическое усечение полей в max_length в Django CharFields

У меня есть поле с набором max_length. Когда я сохраняю экземпляр модели, а значение поля больше, чем max_length, Django применяет этот параметр max_length на уровне базы данных. (См. Django docs на моделях: http://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.CharField.max_length)

Однако, поскольку я использую Postgres, я получаю исключение DatabaseError, подобное этому:

DatabaseError: value too long for type character varying(1000)

Я бы предпочел вместо этого автоматически обрезать значение (поэтому у меня нет исключения). Теперь я могу сделать это вручную, но я бы очень хотел, чтобы все мои модели автоматически усекали значение. (Не обязательно разумно. Просто отрезать его на 999-м символе в порядке.)

Должен ли я просто написать пользовательский класс, который импортирует из models.Model и переопределить метод save(), перебирать через каждое _meta.field, проверять max_length и затем усекать? Это кажется неэлегантным, и должен быть лучший способ.

4b9b3361

Ответ 1

Вы можете создать настраиваемое поле, которое автоматически обрезает поле (я думаю, что этот код должен работать, но дважды проверьте его):

class TruncatingCharField(models.CharField):
    def get_prep_value(self, value):
        value = super(TruncatingCharField,self).get_prep_value(value)
        if value:
            return value[:self.max_length]
        return value

Затем вместо использования models.CharField в вашем файле models.py вы просто используете TruncatingCharField.

get_prep_value подготавливает значение для поля для вставки в базу данных, поэтому это идеальное место для усечения.

Ответ 2

Почему бы вам не использовать ModelForm. ModelForm применяет проверку, устанавливая значение max_length по умолчанию для моделирования свойства max_length поля и повышая правильную ошибку проверки при вызове form.is_valid(). Таким образом, вам не нужно сохранять форму, пока форма не будет проверена.

Или, если вы хотите, чтобы вы молча пропустили наиболее подходящие для вас варианты проверки и усечения, напишите простую форму django и напишите чистый метод, который обрезает строку ввода до max_length и возвращает разделенные данные. Возьмите данные из form.cleaned_data после проверки формы и сохранения объекта.

Все, учитывая факт, Forms предназначены для проверки данных перед переходом в DB.

Ответ 3

Почему бы вам не использовать TextField? Из руководства:

Для больших объемов текста используйте TextField.

Ответ 4

Это кажется неэлегантным, и должен быть лучший способ.

Единственная причина, по которой поведение truncate когда-либо случается в первую очередь, состоит в том, что MySQL не соблюдает стандарт SQL. Выброс исключения является правильным ответом при попытке вставить строку в поле VARCHAR, которая недостаточно широка, чтобы удерживать ее. MySQL усекает и вставляет вместо этого.

Если вы хотите портить свои данные, то вам придется сделать это вручную - PostgreSQL никогда не сделает это за вас.