在Django模型中指定mySQL ENUM
时间:2020-03-05 18:41:50 来源:igfitidea点击:
如何在Django模型中指定和使用ENUM?
解决方案
回答
从Django文档中:
MAYBECHOICE = ( ('y', 'Yes'), ('n', 'No'), ('u', 'Unknown'), )
然后在模型中定义一个charfield:
married = models.CharField(max_length=1, choices=MAYBECHOICE)
如果我们不喜欢字母,可以对整数字段进行相同的操作
在数据库中。
在这种情况下,请重写选择:
MAYBECHOICE = ( (0, 'Yes'), (1, 'No'), (2, 'Unknown'), )
回答
使用choices
参数不会使用ENUM db类型。它只会创建VARCHAR或者INTEGER,这取决于我们是否将choices
与CharField或者IntegerField一起使用。通常,这很好。如果在数据库级别使用ENUM类型对我们很重要,则有以下三种选择:
- 使用" ./manage.py sql应用程序名称"查看Django生成的SQL,手动对其进行修改以使用ENUM类型,然后自行运行。如果我们首先手动创建该表,则" ./manage.py syncdb"将不会使它混乱。
- 如果不想每次生成数据库时都手动执行此操作,请将一些自定义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.
回答
如果我们确实要使用数据库的ENUM类型,请执行以下操作:
- 使用Django 1.x
- 认识到应用程序仅适用于某些数据库。
- 困惑于此文档页面:http://docs.djangoproject.com/en/dev/howto/custom-model-fields/#howto-custom-model-fields
祝你好运!
回答
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) )