这一篇主要是介绍django的模型如何创建, 模型的一些参数, 以及数据如何迁移
成都创新互联专注于企业全网营销推广、网站重做改版、奉新网站定制设计、自适应品牌网站建设、H5页面制作、商城建设、集团公司官网建设、外贸营销网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为奉新等各大城市提供网站开发制作服务。
项目地址:https://gitee.com/ccnv07/django_example
首先我们先创建一个会员模块
> cd cms
> python manager.py account
这样就在根目录下创建了一个account文件夹
关于数据库的表模型代码需要写在models.py文件中
account/models.py中的文件代码
最终生成的数据表的名称为模块名_类名
模型中基本分为三块
模型不仅会影响到数据库表的创建, 而且会影响到后台表单的展示
我们只介绍最常用的几种模型字段和选项说明
CharField字段
对应的是数据库的varchar字段, 保存字符串
对应的表单是input类型max_length
可以指定字符串的长度, 对应的生成的sql代码就是varchar(64)
DateField字段
对应数据库的date字段, 保存年-月-日的信息
对应表单中的日期选择控件auto_now_add
是指定在数据新增时, 自动写入时间auto_now
是无论新增还是更新数据, 此字段都会更新为当前时间
auto_now_add和auto_now不可以同时设置, 否则会提示你
account.Account.update_time: (fields.E160) The options auto_now, auto_now_add, and default are mutually exclusive. Only one of these options may be present
DateTimeField字段
同DateField字段, 只不过是包含日期+时间
EmailField
对应表单的input, 但是会添加邮件格式校验
django里是邮件字段, 其实数据库是varchar字段, 最终继承的是CharField字段, 但是可以辅助验证邮件的格式, 所以它也有max_length
参数
IntegerField
数字字段, 对应数据库的int(11)类型max_length
指定最大长度min_length
指定最小长度choice
指定字段的选项, 格式是((值, 值说明),), 这个参数会影响到后台表单的展示、新增和编辑
SmallIntegerField
存储范围比较小, 其他同IntegerField
TextField
文本类型字段, 对应数据库的text()
这些参数基本在所有字段中都可以设置, 所以单独拿出来介绍一下
null
如果是True, 则可以null值, 默认是False, 但是在TextField字段中, 这个应该一直是False, 设置为True, 数据库会报错
blank
如果是True, 则允许插入空值, 默认是False, 这个插入的是空, 对应字符串是'', 而不是null值
choice
字段的选项值, 设置这个参数后, 后台表单就会变成下拉的格式
db_name
字段名, 如果指定这个, 如果不指定, 采用的是模型类属性的名称小写, 设置了以后, 则使用这个名称
db_index
设置为True, 则会在这个字段上创建索引
default
设置字段的默认值, 不仅支持普通的数据类型, 也支持函数
def contact_default():
return {"email": "to1@example.com"}
contact_info = JSONField("ContactInfo", default=contact_default)
editable
如果是False, 则不会展示在后台或者任何其他的ModelForm中, 也会跳过模型验证, 默认是True
error_messages
设置验证失败时的错误信息
account = account = models.CharField(max_length=64, blank=True, verbose_name='用户名', error_messages={
'max_length': '最大长度不可超过64个字符'
})
help_text
指定在表单页面的帮助说明问题
primary_key
默认是False, 如果没有指定字段的这个参数, 则django会自动添加一个id字段作为主键。
primary_key=True则必然null=False 并且unique=True
unique
如果是True, 则这个字段必须是唯一的
verbose_name
指定后台中列表页, 新增编辑页面显示的表单字段名称
django中的元类用来设置一些指定的操作, 以及后台的一些设置
class Account(models.Model):
class Meta:
ordering = ['-id']
verbose_name = '会员'
verbose_name_plural = '会员管理'
class Meta就是一个元类
app_label
指定此模型所属的模块名, 如果更改后, 会影响到表的名称
base_manager_name
指定模型的基本管理者类名称(就按照管理者来翻译吧)
先简单说一下, 我们在使用django查询的时候, 都会执行django.objects.
那么为什么要这么麻烦的加一个objects呢?
其实objects的作用就是返回了一个manager类, 而Model其实只是模型结构的声明, Manager类才是真正操作数据库的类
db_table
指定数据库表名
default_manager_name
默认管理者的名称, 和base_manager_name类似, 稍后专门会有一篇文章解释
get_latest_by
排序用的, 只能设置DateField, DateTimeField, IntegerField. 这个会作用于Manager的latest()和earliest()方法
# Latest by ascending order_date.
get_latest_by = "order_date"
# Latest by priority descending, order_date ascending.
get_latest_by = ['-priority', 'order_date']
解释一下, django中-priority代表倒序, priority代表正序
order
类似get_latest_by, 执行查询时, 会影响到排序方式order_by这个方法
indexes
设置表的索引
from django.db import models
class Customer(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
class Meta:
indexes = [
models.Index(fields=['last_name', 'first_name']),
models.Index(fields=['first_name'], name='first_name_idx'),
]
fields 指定索引列, name是索引名
unique_together
指定唯一字段
unique_together = ("driver", "restaurant")
在写入数据时, driverhe restaurant必须是唯一的
verbose_name
指定一个表的显示名称, 影响后台面包屑导航的显示名称
verbose_name_plural
影响后台列表页的显示名称
以上就把关于模型常用的参数, 属性都介绍了, 对照demo的代码大家可以理解一下
执行数据迁移之前, 先要将模块注册到项目中, 因为django的模块设计是可插拔的, 减少耦合性
# cms/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.staticfiles',
'account' # 将模块名写入list中就完成了注册
]
如果不执行注册, 那么项目就不会加载这个模块, 也无法执行数据迁移、模块访问, 包括后台的操作了
> cd cms
> python manager.py makemigrations
会提示
Migrations for 'account':
account/migrations/0001_initial.py
- Create model Account
打开account/migrations/0001_initial.py
文件
可以看到我们声明的Model已经转换为了迁移文件, 到这一步其实还没有将模型同步到数据库
python manager.py showmigrations account
account
[ ] 0001_initial
说明0001_initial还未迁移, 如果迁移完成则会变成[x]0001_initial
接下来我们查看一下执行迁移会出发的sql
python manage.py sqlmigrate account 0001_initial
BEGIN;
--
-- Create model Account
--
CREATE TABLE `account_account` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `account` varchar(200) NOT NULL UNIQUE, `password` varchar(32) NOT NULL, `email` varchar(32) NOT NULL, `phone` varchar(11) NOT NULL, `status` integer NOT NULL, `create_time` datetime(6) NOT NULL, `update_time` datetime(6) NOT NULL);
COMMIT;
不同的数据库返回的sql可能是不同的
python manager.py migrate
返回
Operations to perform:
Apply all migrations: account, admin, article, auth, contenttypes, sessions
Running migrations:
Applying account.0001_initial... OK
则说明迁移成功, 打开MySQL管理工具就可以看到我们创建的account_account
这个表了