model操作记录
python manage.py makemigrations appName
:模型修改保存记录文件中
appName
:应用名,可以不输入
python manage.py migrate
:将模型应用到数据库上,对模型进行增、删、修改
一、分包管理模型
- 使用
python manage.py startapp xxx
新建应用,删除models.py
文件 - 在应用目录下新增文件夹
models
,并在其下新增文件__init__.py
- 将模型归类到不同的文件中,文件保存在
models
文件夹中 - 在
__init__.py
引入新增的模型
# coding=utf-8
from .req import RequestApi,RequestItem
二、模型的继承
1.抽象类继承,自定义将models
转化为dict
的方法
新建父model
:BasicData
,包含方法to_dict()
class BasicData(models.Model):
create_time = models.DateTimeField(db_column='CreateTime', auto_now_add=True)
update_time = models.DateTimeField(db_column='UpdateTime', auto_now=True)
"""
将model转化为dict,此方法与 model_to_dict() 相同
"""
def to_dict(self, fields=None, exclude=None):
data = {}
for f in self._meta.concrete_fields + self._meta.many_to_many:
value = f.value_from_object(self)
if fields and f.name not in fields:
continue
if exclude and f.name in exclude:
continue
if isinstance(f, models.ManyToManyField):
value = [i.id for i in value] if self.pk else None
if isinstance(f, models.DateTimeField):
value = value.strftime('%Y-%m-%d %H:%M:%S') if value else None
data[f.name] = value
return data
class Meta:
abstract = True
重点:模型的Meta类里添加abstract=True
元数据项
然后,子类继承BasicData
class Parameter(BasicData):
#.....
class Meta:
db_table = 'Parameter'
这里有几点要特别说明:
- 抽象基类中有的元数据,子模型没有的话,直接继承;
- 抽象基类中有的元数据,子模型也有的话,直接覆盖;
- 子模型可以额外添加元数据;
- 抽象基类中的
abstract=True
这个元数据不会被继承。也就是说如果想让一个抽象基类的子模型,同样成为一个抽象基类,那你必须显式的在该子模型的Meta
中同样声明一个abstract = True
; - 有一些元数据对抽象基类无效,比如
db_table
,首先是抽象基类本身不会创建数据表,其次它的所有子类也不会按照这个元数据来设置表名。
三、字段类型设置
1、CharField
models.CharField(db_column='Key',max_length=128)
db_column
:数据库列表
max_length
:最多长度
blank=True
:可以为空白
null=True
:允许为null
unique= True
:是否唯一,不允许重复
2、设置创建时间和最后修改时间
models.DateTimeField(db_column='CreateTime', auto_now_add=True)
models.DateTimeField(db_column='UpdateTime', auto_now=True)
auto_now_add
:在创建时自动赋值当前时间,之后的操作不会被修改
auto_now
:每次修改会赋值当前时间
3、设置枚举类型
- 1.使用tuples实现枚举
# 设置枚举类型,数据类型:tuples
# 第一列:1;2;3 表示数据库存储值
# 第二列:为前端显示的值
PARAM_TYPE = (
(0,'default'),
(1,'header'),
(2,'url'),
(3,'form'),
)
models.CharField(db_column='ParamType',choices=argument.PARAM_TYPE, default=0, max_length=2)
choices
:设置的枚举
default
:必须设置默认值
max_length
:必填,此次容易忽略
- 2.使用枚举类
- 首先设置枚举类,枚举必须继承
Enum
- 首先设置枚举类,枚举必须继承
from enum import Enum
class OptionType(Enum):
skip = 1
skipIf = 2
skipUnless = 3
variables = 4
- 在
model
类中使用
from django.db import models
class WeOptions(models.Model):
name = models.CharField(db_column='Name', max_length=128, unique=True)
option_type = models.CharField(
db_column='OptionType',
max_length=2,
choices=[(tag.name,tag.value,) for tag in OptionType]
)
def save(self, *args, **kwargs):
# 正常使用时,option_type=OptionType.variables.name
# 允许直接传入枚举,option_type=OptionType.variables
if isinstance(self.option_type,Enum):
self.option_type = self.option_type.name
# 一定要继承父类的save()方法,否则不能保存到DB
super().save(*args, **kwargs)
- 使用
myoptions = WeOptions(
name='参数1',
option_type=OptionType.variables
)
myoptions.save()
参考:django models choices的三种实现方式
4、设置多对一关系(外键)
外键要定义在‘多’的一方!
class Parameter(BasicData):
#......
request = models.ForeignKey(to='Request',on_delete=models.CASCADE)
class Request(BasicData):
#.......
参数说明:
-
to
:需要管理的model类名,例:- 同APP内:
'className'
- 不同APP:
'appName.className'
- 递归:
'self'
- 同APP内:
-
on_delete
:被外键关联的对象被删除时,SQL约束执行相应操作-
CASCADE
:模拟SQL语言中的ON DELETE CASCADE
约束,将定义有外键的模型对象同时删除!(该操作为当前Django
版本的默认操作!) -
PROTECT
:阻止上面的删除操作,但是弹出ProtectedError
异常 -
SET_NULL
:将外键字段设为null
,只有当字段设置了null=True
时,方可使用该值。 -
SET_DEFAULT
:将外键字段设为默认值。只有当字段设置了default
参数时,方可使用。 -
DO_NOTHING
:什么也不做。 -
SET()
:设置为一个传递给SET()
的值或者一个回调函数的返回值。注意大小写。
-
三、数据操作
1、数据整合
自定义dict过滤的方法:
# 过滤dict中的数据
def dictFilter ( collection, fields = None, exclude = None ):
# 将object转化为dict
if isinstance ( collection, (str, bytes) ):
collection = json.loads ( collection, encoding = 'utf-8' )
# 不是dict的直接返回collection
if not isinstance ( collection, dict ):
return collection
data = {}
for f in collection.keys ( ):
if fields:
# 过滤
if isinstance ( fields, list ) and f not in fields:
continue
# 替换
if isinstance( fields, dict ):
if f in fields.keys():
data[fields[f]] = collection[f]
continue
else:
continue
# 排除
if exclude and f in exclude:
continue
data[f] = collection[f]
return data
2.增
- 方法一
使用对应的dict新增数据,推荐
value = dictFilter(body,fields=['key','value','description',
'enabled','param_type','id_delete'])
if value['key'] and value['value']:
_f = models.Parameter.objects.create(**value)
- 方法二
_t = models.Parameter.objects.create(key=value['key'])
- 方法三
f = models.RequestItem(key =value['key'])
f.save()
- 方法四
t = models.Parameter()
t.key = value['key']
t.save()