#python #django #django-models #python-3.9 #django-3.2
Вопрос:
Я пытаюсь создать поле автоматического приращения для крошечного целого числа, такого как int(3).
Если я попытаюсь AutoField
, он создаст длину 11. Если я использую max_length
, миграция игнорирует это.
SmallIntegerField
дает int(6) без автоматического приращения.
Мое определение модели:
class tblroles(models.Model):
role_id = SmallIntegerField(primary_key=True, verbose_name="role_id")
name = CharField(max_length=20)
is_active = BooleanField(default=False)
Комментарии:
1. Какой сервер базы данных вы используете?
2. Я использую mysql.
Ответ №1:
У Джанго нет tinyint
поля. Но вы можете создать пользовательское автоматически увеличивающееся автоматическое поле, переопределив db_type(...)
метод как
from django.db.models import SmallAutoField
class TinyAutoField(SmallAutoField):
def db_type(self, connection):
return "tinyint AUTO_INCREMENT"
Использование
class FooBar(models.Model):
id = TinyAutoField(
primary_key=True,
)
def __str__(self):
return f"{self.id}"
PS: Это решение отлично работает в MySQL 8.0
Ответ №2:
SmallIntegerField
является smallint
(максимальное значение со знаком 32767
, ширина отображения 6
) в MySQL.
Я полагаю, вы хотите tinyint
(максимальное значение со знаком 127
, ширина отображения 3
) в MySQL.
class TinyAutoField(models.SmallAutoField):
def db_type(self, connection):
if connection.vendor == 'mysql':
return 'tinyint AUTO_INCREMENT'
return super().db_type(connection)
def rel_db_type(self, connection):
if connection.vendor == 'mysql':
return 'tinyint'
return super().db_type(connection)
Использование:
class tblroles(models.Model):
# role_id = SmallIntegerField(primary_key=True, verbose_name="role_id") # Change this
role_id = TinyAutoField(primary_key=True, verbose_name="role_id") # to this
# ...
Но если вам нужен литерал int(3)
(максимальное значение со знаком 2147483647
, ширина отображения 3
) в MySQL.
class AutoField(models.AutoField):
def __init__(self, *args, **kwargs):
self.display_width = kwargs.pop('display_width', None)
super().__init__(*args, **kwargs)
def db_type(self, connection):
if connection.vendor == 'mysql' and self.display_width:
return 'int(%s) AUTO_INCREMENT' % self.display_width
return super().db_type(connection)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
if self.display_width:
kwargs['display_width'] = self.display_width
return name, path, args, kwargs
Использование:
class tblroles(models.Model):
# role_id = SmallIntegerField(primary_key=True, verbose_name="role_id")
role_id = AutoField(primary_key=True, verbose_name="role_id", display_width=3)