Char вместо Varchar для поля Джанго

У меня есть несколько текстовых столбцов, которые содержат ровно 2 символа. Когда я использую models.CharField с max_length=2, он все равно создает Varchar. Я проверил https://docs.djangoproject.com/en/5.0/ref/models/fields/ и не могу найти тип поля или параметр, который нужно передать, чтобы получить столбец Char(x) вместо Varchar( Икс). TextField тоже для этого не подходит. Насколько я понимаю, Varchar использует 2 дополнительных байта для хранения информации о длине, и здесь это пустая трата. Итак, как мне заставить Django создать столбец фиксированной длины символов?

Редактировать: Просматривая это (CharField с фиксированной длиной, как?), кажется, что нет способа заставить Django создать Char, он всегда будет создавать Varchar, а валидаторы минимальной-максимальной длины можно поставить поверх.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
118
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Django действительно всегда будет использовать VARCHAR, поэтому, если вы не напишете свой собственный бэкэнд, он всегда будет иметь VARCHAR(2). Однако вы можете добавить MinLengthValidator [Django-doc] и добавить CheckConstraint [Django-doc], чтобы применить это к базе данных:

from django.core.validators import MinLengthValidator
from django.db.models.lookups import GreaterThanOrEqual
from django.db.models.functions import Length


class MyModel(models.Model):
    my_field = models.CharField(max_length=2, validators=[MinLengthValidator(2)])

    class Meta:
        constraints = [
            models.CheckConstraint(
                check=GreaterThanOrEqual(Length('my_field'), 2),
                name='at_least_two_characters',
            )
        ]

Я думаю, вы имели в виду MinLengthValidator вместо MinValueValidator, models.CheckConstraint вместо models.CheckConstraints и functions.Length вместо lookups.Length. Пробую сейчас.

fishfin 16.04.2024 12:57

@fishfin: ааааааа, да. Спасибо!

willeM_ Van Onsem 16.04.2024 13:01

Я попробовал и lookups.Exact, и lookups.GreaterThanOrEqual, они сгенерировали Postgresql ALTER TABLE "common_country" ADD CONSTRAINT "my_field_constraint" CHECK (LENGTH("my_field") = 2); и то же самое с >= 2 соответственно. Спасибо, что познакомили меня с ограничениями БД в Django. Это также означает, что все ограничения БД, реализованные в Django, должны быть реализованы в БД, поддерживаемых Django. Кстати, это models.CheckConstraint.

fishfin 16.04.2024 13:13

«если вы не напишете свой собственный бэкэнд» на самом деле нет, вы также можете создать собственное поле модели. (Один из примеров в документации, а именно BetterCharField, на самом деле может подойти для OP)

Abdul Aziz Barkat 16.04.2024 13:31

@AbdulAzizBarkat: Я думаю, что сложнее всего перевести его в поле CHAR(2), поскольку бэкэнды обычно сопоставляются только с VarChar(...): github.com/django/django/blob/main/django/db/backends/mysql/‌​ …

willeM_ Van Onsem 16.04.2024 13:35

@willeM_VanOnsem проверьте эту часть в документации вот для чего нужны методы db_type и rel_db_type. Наряду с проверкой значения connection.vendor должно быть возможно определить подходящий тип для использования в соответствующих базах данных.

Abdul Aziz Barkat 16.04.2024 13:39

Другие вопросы по теме