Django默认的数据库是sqlite3,但是在实际生产环境中大多是使用mysql,所以我们需要把数据库改成mysql,大概有2两种方法
1.准备数据库
我们先进入mysql,创建一个数据库
mysql -uroot -p
create database django_demo default charset=utf8;
我们打开Django项目的settings.py配置文件,找到DATABASES字典,修改数据库信息,把原来的信息注释掉
DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': 'localhost', # 数据库主机
'PORT': 3306, # 数据库端口
'USER': 'root', # 数据库用户名
'PASSWORD': 'XXXXXXXX', # 数据库用户密码
'NAME': 'django_demo' # 数据库名字
}
}
2.方法一:pymysql
2.1 安装pymysql
pip install pymysql
2.2 导入pymysql
打开项目的__init__.py,添加pymysql包
import pymysql
pymysql.install_as_MySQLdb()
2.3 创建模型类
我们创建一个子应用(记得注册该应用),打开models.py文件,里面写模型类,一个类表示一个数据表
class BookInfo(models.Model):
"""图书信息:演示一对多,一方"""
btitle = models.CharField(max_length=20, verbose_name='书名')
bpub_date = models.DateField(verbose_name='发布日期')
bread = models.IntegerField(default=0, verbose_name='阅读量')
bcomment = models.IntegerField(default=0, verbose_name='评论量')
is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
class Meta:
"""模型类的元类:用于修改、配置模型类对应的数据表"""
db_table = 'tb_books' # 自定义数据库表名
def __str__(self):
"""定义每个数据对象的显示信息"""
return self.btitle # 输出该模型数据对象时,只输出书名
class HeroInfo(models.Model):
"""英雄信息:演示一对多,多方"""
# 确定性别字段的取值范围
GENDER_CHOICES = (
(0, 'female'),
(1, 'male')
)
hbook = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='英雄属于的图书')
hname = models.CharField(max_length=20, verbose_name='人名')
hgender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别')
hcomment = models.CharField(max_length=200, null=True, verbose_name='描述信息')
is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
class Meta:
db_table = 'tb_heros'
def __str__(self):
return self.hname
提示: 关于字段类型和约束,可以看文章后面的表格
如果你需要创建一些只是表名不同但字段是一样的表(水平拆分),可以通过元类类控制表名,例如
def addressPool(t_name):
class AddressPoolMetaclass(models.base.ModelBase):
def __new__(cls, name, bases, attrs):
name += t_name
return models.base.ModelBase.__new__(cls, name, bases, attrs)
class AddressPool(models.Model):
__metaclass__ = AddressPoolMetaclass
id = models.BigIntegerField(null=False, primary_key=True)
address = models.CharField(max_length=255, null=False)
...
class Meta:
db_table = t_name
verbose_name = t_name
verbose_name_plural = verbose_name
return AddressPool
如果某个字段名也不一样,可以通过db_column指明
def chainBalance(t_name, coin_name):
class ChainBalanceMetaclass(models.base.ModelBase):
def __new__(cls, name, bases, attrs):
name += t_name
return models.base.ModelBase.__new__(cls, name, bases, attrs)
class ChainBalance(models.Model):
__metaclass__ = ChainBalanceMetaclass
id = models.BigIntegerField(null=False, primary_key=True)
type = models.IntegerField(null=False)
...
coinname = models.CharField(db_column=coin_name, max_length=30, null=True)
class Meta:
db_table = t_name
verbose_name = t_name
verbose_name_plural = verbose_name
return ChainBalance
2.4 迁移
打开终端或cmd窗口,进入到项目所在位置,执行下面的迁移语句
# 生成迁移文件
python manage.py makemigrations
# 同步到数据库中
python manage.py migrate
2.5 错误
我们在执行数据迁移的时候会发现错误,大概是关于某个类没有decode属性的,我们点击它最后给出的那个链接打开该文件,把decode改为encode,再重启项目,运行,此时迁移应该是没有问题了
但是我这里悲催了,又报了另外一个错,而且我还不知道怎么解决,研究了很久,大概结论是,我的mysql版本跟Django不匹配,我的mysql是5.4.45,Django是2.2.5,又不好升级数据库,所以放弃了。Django2.2版本好像最低支持MySQL5.5
3.方法二:mysqlclient
3.1 安装mysqlclient
打开命令行执行pip安装语句
pip install mysqlclient==1.4.6 -i https://pypi.tuna.tsinghua.edu.cn/simple/
3.2 安装依赖
如果Linux系统执行上面的代码报错了,大概是提示缺少libmysqlclient-dev这个依赖,那我们只要把它安装好再安装mysqlclient即可
1.安装依赖
sudo apt-get install libmysqlclient-dev
2.安装mysqlclient
pip install mysqlclient==1.4.6 -i https://pypi.tuna.tsinghua.edu.cn/simple/
如果安装依赖很慢或者也报错,可以考虑换源
3.3 创建模型类
我们创建一个子应用(记得注册该应用),打开models.py文件,里面写模型类,一个类表示一个数据表
class BookInfo(models.Model):
"""图书信息:演示一对多,一方"""
btitle = models.CharField(max_length=20, verbose_name='书名')
bpub_date = models.DateField(verbose_name='发布日期')
bread = models.IntegerField(default=0, verbose_name='阅读量')
bcomment = models.IntegerField(default=0, verbose_name='评论量')
is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
class Meta:
"""模型类的元类:用于修改、配置模型类对应的数据表"""
db_table = 'tb_books' # 自定义数据库表名
def __str__(self):
"""定义每个数据对象的显示信息"""
return self.btitle # 输出该模型数据对象时,只输出书名
class HeroInfo(models.Model):
"""英雄信息:演示一对多,多方"""
# 确定性别字段的取值范围
GENDER_CHOICES = (
(0, 'female'),
(1, 'male')
)
hbook = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='英雄属于的图书')
hname = models.CharField(max_length=20, verbose_name='人名')
hgender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别')
hcomment = models.CharField(max_length=200, null=True, verbose_name='描述信息')
is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
class Meta:
db_table = 'tb_heros'
def __str__(self):
return self.hname
3.4 迁移
# 生成迁移文件
python manage.py makemigrations
# 同步到数据库中
python manage.py migrate
注意:如果能正常安装,但是执行迁移或SQL语句出错,有可能是因为版本不兼容引起的,可以考虑换MySQL或Django版本
4.常用字段类型
类型 | 说明 |
---|---|
CharField | 字符串,可以用max_length限制最大字符个数 |
IntegerField | 整型 |
DecimalField | 浮点型,max_digits、decimal_places分别表示总位数和小数位数 |
TextField | 文本,一般不超过4000字符 |
BooleanField | 布尔,就是True或False |
AutoField | 自动增长,一般用于主键id,Django会自动创建 |
NullBooleanField | 空布尔,支持Null、True、False |
FloatField | 浮点型 |
DateField | 日期,auto_now表示使用当前日期,crud会改变,auto_now_add在crud后不会主动改变,两者都默认False |
TimeField | 时间 ,参数同上 |
DateTimeField | 日期时间,参数同上 |
FileField | 上传文件字段 |
ImageField | 图片字段,继承于FileField |
5.字段约束
约束 | 说明 |
---|---|
default | 默认 |
primary_key | 若为True则建立主键,默认是False |
null | 若为True则允许为空,默认是False |
unique | 若为True则该字段在表中必须有唯一值,默认是False |
db_column | 字段名,若未指定则使用属性名 |
db_index | 若为True则建立索引,默认是False |