Django model操作记录

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'
  • 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()

你可能感兴趣的:(Django model操作记录)