Django 모델에서 mySQL ENUM 지정
Django 모델에서 ENUM을 지정하고 사용하려면 어떻게 해야 합니까?
Django 문서에서 다음 내용을 참조하십시오.
MAYBECHOICE = (
('y', 'Yes'),
('n', 'No'),
('u', 'Unknown'),
)
모델에 charfield를 정의합니다.
married = models.CharField(max_length=1, choices=MAYBECHOICE)
db에 문자가 없는 경우 정수 필드에 동일한 작업을 수행할 수 있습니다.
이 경우 선택 사항을 다시 작성합니다.
MAYBECHOICE = (
(0, 'Yes'),
(1, 'No'),
(2, 'Unknown'),
)
from django.db import models
class EnumField(models.Field):
"""
A field class that maps to MySQL's ENUM type.
Usage:
class Card(models.Model):
suit = EnumField(values=('Clubs', 'Diamonds', 'Spades', 'Hearts'))
c = Card()
c.suit = 'Clubs'
c.save()
"""
def __init__(self, *args, **kwargs):
self.values = kwargs.pop('values')
kwargs['choices'] = [(v, v) for v in self.values]
kwargs['default'] = self.values[0]
super(EnumField, self).__init__(*args, **kwargs)
def db_type(self):
return "enum({0})".format( ','.join("'%s'" % v for v in self.values) )
사용방법choices
파라미터는 ENUM DB 타입을 사용하지 않고 VARCHAR 또는 INTEGER 중 어느 쪽을 사용하느냐에 따라 작성됩니다.choices
CharField 또는 IntegerField를 사용합니다.대체로 이 정도면 괜찮아요.데이터베이스 수준에서 ENUM 유형을 사용하는 것이 중요한 경우 다음 세 가지 옵션을 사용할 수 있습니다.
- ".manage.py sql appname"을 사용하여 SQL Django가 생성하는 내용을 확인하고 ENUM 유형을 사용하도록 수동으로 수정한 후 직접 실행합니다.먼저 테이블을 수동으로 작성할 경우 "./manage.py syncdb"는 문제가 되지 않습니다.
- DB를 생성할 때마다 수동으로 이 작업을 수행하지 않으려면 일부 사용자 지정 SQL을 appname/sql/modelname에 넣으십시오.sql을 지정하여 적절한 ALTER TABLE 명령을 수행합니다.
- 커스텀 필드 유형을 생성하여 db_type 메서드를 적절하게 정의합니다.
이러한 옵션 중 하나를 사용하여 데이터베이스 간 이동성에 대한 영향을 처리하는 것은 사용자의 책임입니다.옵션 2에서는 데이터베이스 백엔드별 사용자 지정 SQL을 사용하여 ALTER TABLE이 MySQL에서만 실행되도록 할 수 있습니다.옵션 3에서 db_type 메서드는 데이터베이스 엔진을 확인하고 db 컬럼유형을 해당 데이터베이스에 실제로 존재하는 타입으로 설정해야 합니다.
업데이트: 이행 프레임워크가 Django 1.7에 추가되었기 때문에 위의 옵션1과 2는 완전히 폐지되었습니다.어쨌든 옵션 3은 항상 최선의 옵션이었다.새로운 버전의 옵션 1/2에서는, 다음의 복잡한 커스텀 이행이 필요하게 됩니다.SeparateDatabaseAndState
--하지만 정말로 옵션3을 원하는군요.
http://www.b-list.org/weblog/2007/nov/02/handle-choices-right-way/
class Entry(models.Model): LIVE_STATUS = 1 DRAFT_STATUS = 2 HIDDEN_STATUS = 3 STATUS_CHOICES = ( (LIVE_STATUS, 'Live'), (DRAFT_STATUS, 'Draft'), (HIDDEN_STATUS, 'Hidden'), ) # ...some other fields here... status = models.IntegerField(choices=STATUS_CHOICES, default=LIVE_STATUS) live_entries = Entry.objects.filter(status=Entry.LIVE_STATUS) draft_entries = Entry.objects.filter(status=Entry.DRAFT_STATUS) if entry_object.status == Entry.LIVE_STATUS:
데이터베이스에 enum을 저장하지는 않지만 이는 enum을 구현하는 또 다른 쉽고 좋은 방법입니다.
단, 'value'(숫자일 수 있음)를 사용해야 하는 최상위 응답과 달리 기본값을 쿼리하거나 지정할 때마다 'label'을 참조할 수 있습니다.
★★choices
필드에서는 Django 엔드에서 일부 검증을 허용하지만 데이터베이스 엔드에서 열거형 형식을 정의하지는 않습니다.
다른 사용자가 언급했듯이 해결책은 커스텀필드에 지정하는 것입니다.
SQL 백엔드(예: MySQL)를 사용하는 경우 다음과 같이 수행할 수 있습니다.
from django.db import models
class EnumField(models.Field):
def __init__(self, *args, **kwargs):
super(EnumField, self).__init__(*args, **kwargs)
assert self.choices, "Need choices for enumeration"
def db_type(self, connection):
if not all(isinstance(col, basestring) for col, _ in self.choices):
raise ValueError("MySQL ENUM values should be strings")
return "ENUM({})".format(','.join("'{}'".format(col)
for col, _ in self.choices))
class IceCreamFlavor(EnumField, models.CharField):
def __init__(self, *args, **kwargs):
flavors = [('chocolate', 'Chocolate'),
('vanilla', 'Vanilla'),
]
super(IceCreamFlavor, self).__init__(*args, choices=flavors, **kwargs)
class IceCream(models.Model):
price = models.DecimalField(max_digits=4, decimal_places=2)
flavor = IceCreamFlavor(max_length=20)
실행합니다.syncdb
그 표가 어떤 인지 확인해 ENUM
이치노
mysql> SHOW COLUMNS IN icecream;
+--------+-----------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+-----------------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| price | decimal(4,2) | NO | | NULL | |
| flavor | enum('chocolate','vanilla') | NO | | NULL | |
+--------+-----------------------------+------+-----+---------+----------------+
데이터베이스 ENUM 유형을 사용하려면 다음을 수행합니다.
- Django 1.x 사용
- 응용 프로그램은 일부 데이터베이스에서만 작동합니다.
- 다음 매뉴얼 페이지를 참조하십시오.http://docs.djangoproject.com/en/dev/howto/custom-model-fields/ #how to-custom-model-fields
행운을 빕니다.
Django 3.0에는 Enums 지원 기능이 내장되어 있습니다.
매뉴얼에서 다음 항목을 참조하십시오.
from django.utils.translation import gettext_lazy as _
class Student(models.Model):
class YearInSchool(models.TextChoices):
FRESHMAN = 'FR', _('Freshman')
SOPHOMORE = 'SO', _('Sophomore')
JUNIOR = 'JR', _('Junior')
SENIOR = 'SR', _('Senior')
GRADUATE = 'GR', _('Graduate')
year_in_school = models.CharField(
max_length=2,
choices=YearInSchool.choices,
default=YearInSchool.FRESHMAN,
)
이것은 Python만의 구성입니다.데이터베이스 레벨에서는 선택사항이 적용되지 않습니다.데이터베이스에서도 이러한 값을 적용하려는 경우 데이터베이스 제약 조건과 결합할 수 있습니다.
class Student(models.Model):
...
class Meta:
constraints = [
CheckConstraint(
check=Q(year_in_school__in=YearInSchool.values),
name="valid_year_in_school")
]
현재 이러한 추가에 기초한 2개의 github 프로젝트가 있습니다.다만, 이러한 프로젝트가 어떻게 실장되고 있는지는 아직 조사하지 않았습니다.
- 장고-Enum 필드:
Enum은 Django(IntegerField)를 사용합니다. - 장고-Enum 필드:
Python (PEP435) Enum 을jang 、 Dango 、 Python ( PEP435 ) Enum 。
어느 쪽도 DB Enum 타입을 사용하고 있다고는 생각하지 않지만, 첫 번째 타입은 작업 중입니다.
models.py 파일의 맨 위에 Import 후 다음 행을 추가합니다.
enum = lambda *l: [(s,_(s)) for s in l]
언급URL : https://stackoverflow.com/questions/21454/specifying-a-mysql-enum-in-a-django-model
'programing' 카테고리의 다른 글
vue 구성 요소를 글로벌하게 등록하는 중 (0) | 2022.09.19 |
---|---|
Java를 사용하여 이미지 크기를 조정하려면 어떻게 해야 합니까? (0) | 2022.09.19 |
Larabel Alturnal의 "With()" 함수를 사용하여 특정 열 가져오기 (0) | 2022.09.19 |
MYSQL_ROOT_PASSWORD 환경변수가 mariadb 컨테이너에 설정되어 있지 않다. (0) | 2022.09.19 |
Python: 목록에서 요소 찾기 (0) | 2022.09.19 |