답변:
로부터 장고 문서 :
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) )
은 Using choices
를 상기 ENUM DB 유형을 사용하지 않습니다 매개 변수를; choices
CharField 또는 IntegerField와 함께 사용하는지 여부에 따라 VARCHAR 또는 INTEGER를 만듭니다. 일반적으로 이것은 괜찮습니다. ENUM 유형이 데이터베이스 수준에서 사용되는 것이 중요한 경우 다음 세 가지 옵션이 있습니다.
이러한 옵션을 사용하여 데이터베이스 간 이식성에 대한 영향을 처리하는 것은 사용자의 책임입니다. 옵션 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:
이것은 실제로 데이터베이스에 열거 형을 저장하지는 않지만 열거 형을 구현하는 또 다른 훌륭하고 쉬운 방법입니다.
그러나 '값'(숫자 일 수 있음)을 사용해야하는 최고 등급 답변과 달리 기본값을 쿼리하거나 지정할 때마다 '라벨'을 참조 할 수 있습니다.
choices
필드를 설정 하면 Django 쪽에서 일부 유효성 검사가 허용되지만 데이터베이스 쪽에서는 어떤 형태의 열거 형도 정의 되지 않습니다 .
다른 사람들이 언급했듯이 솔루션은 db_type
사용자 정의 필드 를 지정 하는 것입니다.
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 | |
+--------+-----------------------------+------+-----+---------+----------------+
'type "enum" does not exist LINE 1: ....tablename" ADD COLUMN "select_user" ENUM('B', ...'
합니다.
정말로 데이터베이스를 사용하려면 ENUM 유형 :
행운을 빕니다!
현재 두 개의 github 프로젝트가 추가되어 있지만 구현 방법을 정확히 살펴 보지는 않았습니다.
DB enum 유형을 사용하지 않는다고 생각하지만 처음 에는 작동 중입니다.
로부터 문서 :
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")
]