1.原理
通过ORM与数据库交互,如更换数据库只需要更改运行环境的配置。
参见“Django项目的流程文章”
ORM是“对象-关系-映射”的简称,主要任务是:
- 根据对象的类型生成表结构
- 将对象、列表的操作,转换为sql语句
- 将sql查询到的结果转换为对象、列表
2.模型类(models.Model)及属性用法
该类继承models.Model,用于定义一个表,不直接与数据库交互,此类的对象就是一条数据
例子:
class BookInfo(models.Model):
定义类属性代表字段,属性名不能用连续的下划线__
例子:
btitle = models.CharField(max_length=20)
字段分为多种类型:
- AutoField:一个根据实际ID自动增长的IntegerField,通常不指定
- 如果不指定,一个主键字段将自动添加到模型中
- BooleanField:true/false 字段,此字段的默认表单控制是CheckboxInput
- NullBooleanField:支持null、true、false三种值
- CharField(max_length=字符长度):字符串,默认的表单样式是 TextInput
- TextField:大文本字段,一般超过4000使用,默认的表单控件是Textarea
- IntegerField:整数
- DecimalField(max_digits=None, decimal_places=None):使用python的Decimal实例表示的十进制浮点数
- DecimalField.max_digits:位数总数
- DecimalField.decimal_places:小数点后的数字位数
- FloatField:用Python的float实例来表示的浮点数
- DateField[auto_now=False, auto_now_add=False]):使用Python的datetime.date实例表示的日期
- 参数DateField.auto_now:每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false
- 参数DateField.auto_now_add:当对象第一次被创建时自动设置当前时间,用于“创建”的时间戳,它总是使用当前日期,默认为false
- 该字段默认对应的表单控件是一个TextInput. 在管理员站点添加了一个JavaScript写的日历控件,和一个“Today"的快捷按钮,包含了一个额外的invalid_date错误消息键
- auto_now_add, auto_now, and default 这些设置是相互排斥的,他们之间的任何组合将会发生错误的结果
- TimeField:使用Python的datetime.time实例表示的时间,参数同DateField
- DateTimeField:使用Python的datetime.datetime实例表示的日期和时间,参数同DateField
- FileField:一个上传文件的字段
- ImageField:继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image
- 一般不使用上诉两条,文件被保存在服务器中,数据库只保存文件在服务器中的地址。
字段选项代表各种约束,用以保证数据的正确性
- 在设置字段对象时,用关键字参数定义
- null:如果为True,Django 将空值以NULL 存储到数据库中,默认值是 False
- blank:如果为True,则该字段允许为空白,默认值是 False。对比:null是数据库范畴的概念,blank是表单验证证范畴的
- db_column:字段的名称,如果未指定,则使用属性的名称
- db_index:若值为 True, 则在表中会为此字段创建索引
- default:默认值,在数据库表结构中现实为NULL,但给表添加数据时可以使用。
- primary_key:若为 True, 则该字段会成为模型的主键字段
- unique:如果为 True, 这个字段在表中必须有唯一值
表间的关系也用类属性表示包含:
例子:
class HeroInfo(models.Model):
hbook = models.ForeignKey('BookInfo')
关系分为三种:
- ForeignKey:一对多,将字段定义在多的端中
- ManyToManyField:多对多,将字段定义在两端中
- OneToOneField:一对一,将字段定义在任意一端中
表间访问:
一访问多:对象.模型类小写_set
book.heroinfo_set#一本书中包含的英雄,为一个set
多访问一,对象.属性_id
hero.book_id#英雄所在的书名
定义数据表的名称用元选项:class BookInfo(models.Model):
class Meta:
db_table="bookinfo"#指定表名称
objects属性:
继承自Manager类,用于数据库交互
如果自定义了一个类属性继承了Manager类,objects属性作废
用于与数据库交互,是ORM的核心, 自定义Manager类属性的应用:
改写manager类方法,实现逻辑删除
class BookInfoManager(models.Manager):
def get_queryset(self):#重写Manager类的方法
return super(BookInfoManager, self).get_queryset().filter(isDelete=False)#筛选出没有被逻辑删除的对象
class BookInfo(models.Model):
...
books = BookInfoManager()#重新定义类属性,调用manager类与数据库交互
利用manager对象,简化创建模型类的对象class BookInfoManager(models.Manager):
def create_book(self, title, pub_date):#定义一个方法,简化创建模型类对象
book = self.model()
book.btitle = title
book.bpub_date = pub_date
book.bread=0#可以设置默认值
book.bcommet=0
book.isDelete = False
return book
class BookInfo(models.Model):
...
books = BookInfoManager()#定义一个模型类调用管理类
调用:book=BookInfo.books.create_book("abc",datetime(1980,1,1))
保存:book.save()