Steve, jika Anda bermaksud menggunakan tipe MySQL ENUM, maka Anda kurang beruntung, sejauh yang saya tahu Django tidak menyediakan dukungan untuk itu (fitur itu tidak tersedia di semua DB yang didukung oleh Django). Jawaban yang diberikan oleh Paul berfungsi, tetapi itu tidak akan menentukan tipe di DB.
Seperti yang dikatakan @Carl Meyer dalam jawabannya, ini TIDAK membuat kolom ENUM di database. Ini membuat kolom VARCHAR atau INTEGER, jadi tidak benar-benar menjawab pertanyaan.
Ariel
Bisakah saya menambahkan fitur pilihan dengan bidang integer? @fulmicoton
Ilyas karim
36
from django.db import models
classEnumField(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 inself.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 inself.values))
Pada django 1.2, anda perlu menambahkan parameter kedua, koneksi, ke db_type def.
Hans Lawrenz
2
Lalu apa yang terjadi dengan codecatelog? Lokos seperti itu bisa menjadi ide yang bagus .... Saya mendapatkan 404 sekarang - bahkan untuk halaman root.
Danny Staple
33
Menggunakan choicesparameter tidak akan menggunakan tipe ENUM db; itu hanya akan membuat VARCHAR atau INTEGER, tergantung pada apakah Anda menggunakan choicesCharField atau IntegerField. Secara umum, ini baik-baik saja. Jika penting bagi Anda bahwa tipe ENUM digunakan di tingkat database, Anda memiliki tiga opsi:
Gunakan "./manage.py sql appname" untuk melihat SQL yang dihasilkan Django, ubah secara manual untuk menggunakan tipe ENUM, dan jalankan sendiri. Jika Anda membuat tabel secara manual terlebih dahulu, "./manage.py syncdb" tidak akan mengacaukannya.
Jika Anda tidak ingin melakukan ini secara manual setiap kali Anda membuat DB, letakkan beberapa SQL kustom di appname / sql / modelname.sql untuk melakukan perintah ALTER TABLE yang sesuai.
Dengan salah satu opsi ini, Anda bertanggung jawab untuk menangani implikasi portabilitas lintas database. Pada opsi 2, Anda dapat menggunakan SQL kustom khusus database-backend untuk memastikan ALTER TABLE Anda hanya berjalan di MySQL. Di opsi 3, metode db_type Anda perlu memeriksa mesin database dan menyetel jenis kolom db ke jenis yang sebenarnya ada di database itu.
PEMBARUAN : Sejak kerangka migrasi ditambahkan di Django 1.7, opsi 1 dan 2 di atas seluruhnya sudah usang. Opsi 3 selalu merupakan opsi terbaik. Versi baru dari opsi 1/2 akan melibatkan migrasi ubahsuaian yang kompleks menggunakan SeparateDatabaseAndState- tetapi sebenarnya Anda menginginkan opsi 3.
Ini adalah cara lain yang bagus dan mudah untuk mengimplementasikan enum meskipun tidak benar-benar menyimpan enum di database.
Namun itu memungkinkan Anda untuk mereferensikan 'label' setiap kali menanyakan atau menentukan default sebagai lawan dari jawaban berperingkat teratas di mana Anda harus menggunakan 'nilai' (yang mungkin berupa angka).
Pengaturan choicespada lapangan akan memperbolehkan beberapa validasi pada akhir Django, tetapi itu tidak akan mendefinisikan bentuk apapun dari tipe yang disebutkan pada akhir basis data.
Seperti yang disebutkan orang lain, solusinya adalah menentukan db_typepada bidang khusus.
Jika Anda menggunakan backend SQL (misalnya MySQL), Anda dapat melakukannya seperti ini:
from django.db import models
classEnumField(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):ifnot all(isinstance(col, basestring)for col, _ in self.choices):raiseValueError("MySQL ENUM values should be strings")return"ENUM({})".format(','.join("'{}'".format(col)for col, _ in self.choices))classIceCreamFlavor(EnumField, models.CharField):def __init__(self,*args,**kwargs):
flavors =[('chocolate','Chocolate'),('vanilla','Vanilla'),]
super(IceCreamFlavor, self).__init__(*args, choices=flavors,**kwargs)classIceCream(models.Model):
price = models.DecimalField(max_digits=4, decimal_places=2)
flavor =IceCreamFlavor(max_length=20)
Jalankan syncdb, dan periksa tabel Anda untuk melihat bahwa tabel ENUMdibuat dengan benar.
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||+--------+-----------------------------+------+-----+---------+----------------+
Jawaban yang Sangat Bermanfaat! Tetapi ini tidak akan berfungsi untuk PostgreSQL. Alasannya adalah PostgreSQL ENUM tidak mendukung default. Di PostgreSQL pertama kita harus membuat CREATE DOMAIN atau CREATE TYPE. Reff 8.7. Jenis Enumerasi Saya mencoba trik @ David dan itu berfungsi dengan baik dengan MySQL tetapi dalam pekerjaan PostgrSQL berakhir dengan kesalahan 'type "enum" does not exist LINE 1: ....tablename" ADD COLUMN "select_user" ENUM('B', ...'.
Grijesh Chauhan
6
Jika Anda benar-benar ingin menggunakan database Anda, tipe ENUM:
Gunakan Django 1.x
Kenali aplikasi Anda hanya akan bekerja pada beberapa database.
Saat ini ada dua proyek github berdasarkan penambahan ini, meskipun saya belum melihat secara tepat bagaimana penerapannya:
Django-EnumField :
Menyediakan bidang model pencacahan Django (menggunakan IntegerField) dengan enum yang dapat digunakan kembali dan validasi transisi.
Django-EnumFields :
Paket ini memperbolehkan Anda menggunakan enum Python (gaya PEP435) nyata dengan Django.
Saya tidak berpikir keduanya menggunakan tipe enum DB, tetapi mereka sedang dalam pengerjaan untuk yang pertama.
Sekarang, ketahuilah bahwa ini tidak memaksakan pilihan pada level database, ini hanya konstruksi Python. Jika Anda juga ingin menerapkan nilai tersebut di database, Anda dapat menggabungkannya dengan batasan database:
Jawaban:
Dari dokumentasi Django :
Dan Anda menentukan charfield dalam model Anda:
Anda dapat melakukan hal yang sama dengan bidang integer jika Anda tidak ingin memiliki huruf di db Anda.
Jika demikian, tulis ulang pilihan Anda:
sumber
sumber
Menggunakan
choices
parameter tidak akan menggunakan tipe ENUM db; itu hanya akan membuat VARCHAR atau INTEGER, tergantung pada apakah Anda menggunakanchoices
CharField atau IntegerField. Secara umum, ini baik-baik saja. Jika penting bagi Anda bahwa tipe ENUM digunakan di tingkat database, Anda memiliki tiga opsi:Dengan salah satu opsi ini, Anda bertanggung jawab untuk menangani implikasi portabilitas lintas database. Pada opsi 2, Anda dapat menggunakan SQL kustom khusus database-backend untuk memastikan ALTER TABLE Anda hanya berjalan di MySQL. Di opsi 3, metode db_type Anda perlu memeriksa mesin database dan menyetel jenis kolom db ke jenis yang sebenarnya ada di database itu.
PEMBARUAN : Sejak kerangka migrasi ditambahkan di Django 1.7, opsi 1 dan 2 di atas seluruhnya sudah usang. Opsi 3 selalu merupakan opsi terbaik. Versi baru dari opsi 1/2 akan melibatkan migrasi ubahsuaian yang kompleks menggunakan
SeparateDatabaseAndState
- tetapi sebenarnya Anda menginginkan opsi 3.sumber
http://www.b-list.org/weblog/2007/nov/02/handle-choices-right-way/
Ini adalah cara lain yang bagus dan mudah untuk mengimplementasikan enum meskipun tidak benar-benar menyimpan enum di database.
Namun itu memungkinkan Anda untuk mereferensikan 'label' setiap kali menanyakan atau menentukan default sebagai lawan dari jawaban berperingkat teratas di mana Anda harus menggunakan 'nilai' (yang mungkin berupa angka).
sumber
Pengaturan
choices
pada lapangan akan memperbolehkan beberapa validasi pada akhir Django, tetapi itu tidak akan mendefinisikan bentuk apapun dari tipe yang disebutkan pada akhir basis data.Seperti yang disebutkan orang lain, solusinya adalah menentukan
db_type
pada bidang khusus.Jika Anda menggunakan backend SQL (misalnya MySQL), Anda dapat melakukannya seperti ini:
Jalankan
syncdb
, dan periksa tabel Anda untuk melihat bahwa tabelENUM
dibuat dengan benar.sumber
'type "enum" does not exist LINE 1: ....tablename" ADD COLUMN "select_user" ENUM('B', ...'
.Jika Anda benar-benar ingin menggunakan database Anda, tipe ENUM:
Semoga berhasil!
sumber
Saat ini ada dua proyek github berdasarkan penambahan ini, meskipun saya belum melihat secara tepat bagaimana penerapannya:
Menyediakan bidang model pencacahan Django (menggunakan IntegerField) dengan enum yang dapat digunakan kembali dan validasi transisi.
Paket ini memperbolehkan Anda menggunakan enum Python (gaya PEP435) nyata dengan Django.
Saya tidak berpikir keduanya menggunakan tipe enum DB, tetapi mereka sedang dalam pengerjaan untuk yang pertama.
sumber
Django 3.0 memiliki dukungan bawaan untuk Enums
Dari dokumentasi :
Sekarang, ketahuilah bahwa ini tidak memaksakan pilihan pada level database, ini hanya konstruksi Python. Jika Anda juga ingin menerapkan nilai tersebut di database, Anda dapat menggabungkannya dengan batasan database:
sumber
Di bagian atas file models.py Anda, tambahkan baris ini setelah Anda mengimpor:
sumber