Model
ORM简介
MVC 框架中包括一个重要的部分,就是 ORM,它实现了数据模型与数据库的解耦
即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库
ORM 即Object-Relational Mapping是“对象-关系-映射”的简称,主要任务是:
o 根据对象的类型生成表结构
o 将对象、列表的操作,转换为 sql 语句
o 将 sql 查询到的结果转换为对象、列表
Django 中的模型包含存储数据的字段和约束,对应着数据库中唯一的表
ORM分为两种:
DB First 数据库里先创建数据库表结构,根据表结构生成类,根据类操作数据库
Code First 先写代码,执行代码创建数据库表结构
主流的orm都是code first。django 的orm也是code first,所以学的时候,本质就分
为两块:
根据类自动创建数据库表
根据类对数据库表中的数据进行各种操作
优点:
摆脱复杂的SQL操作,适应快速开发;
让数据结构变得简洁;
数据库迁移成本更低
注意:数据库django不能创建,需要自己提前创建
开发流程
- 在 models.py 中定义模型类,要求继承自 models.Model
- 把应用加入settings.py 文件的installed_app 项
- 生成迁移文件
- 执行迁移生成表
- 使用模型类进行crud 操作
定义模型
在模型中定义属性,会生成表中的字段
模型类要求继承自 models.Model
属性命名限制
不能是python 的保留关键字
由于django 的查询方式,不允许使用连续的下划线
定义属性 - 导入from django.db import models
- 通过models.Field 创建字段类型的对象,赋值给属性
对于重要数据都做逻辑删除,不做物理删除,实现方法是定义 isDelete 属性,类型为
BooleanField,默认值为 False
btitle = models.CharField(max_length=20)
字段类型
AutoField:一个根据实际 ID自动增长的 IntegerField
django 会为表增加自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置
某属性为主键列后,则 django 不会再生成默认的主键列
id = models.AutoField(primary_key=True)
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
auto_now_add, auto_now, and default 这些设置是相互排斥的,他们之间的任
何组合将会发生错误的结果
TimeField:使用 Python 的 datetime.time 实例表示的时间,参数同 DateField
DateTimeField:使用 Python 的 datetime.datetime 实例表示的日期和时间,参数同
DateField
FileField:一个上传文件的字段
ImageField:继承了 FileField 的所有属性和方法,但对上传的对象进行校验,确保它是
个有效的image
上传路径设置:
字段选项STATICFILES_DIRS=[
os.path.join(BASE_DIR,'static')
]
MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")
通过字段选项,可以实现对字段的约束
在字段对象时通过关键字参数指定
null:如果为True,Django 将空值以NULL 存储到数据库中,默认值是 False
blank:如果为True,则该字段允许为空白,默认值是 False
对比:null是数据库范畴的概念,blank 是表单验证证范畴的
如果一个字段设置为blank=True,表单验证时允许输入一个空值。而blank=False,
则该项必需输入数据。
db_column:字段的名称,如果未指定,则使用属性的名称
db_index:若值为 True, 则在表中会为此字段创建索引
default:默认值
primary_key:若为 True, 则该字段会成为模型的主键字段
unique:如果为True,该字段在表中必须有唯一的值
help_text:会在form 表单控件中显示 help 文本
关系
关系的类型包括
o ForeignKey:一对多,将字段定义在多的端中
o ManyToManyField:多对多,将字段定义在两端中
o OneToOneField:一对一,将字段定义在任意一端中
用一访问多:对象.模型类小写_set
bookinfo.heroinfo_set
django 默认每个主表的对象都有一个是外键的属性,可以通过它来查询到子表的信息。
这个属性的名称默认是以子表的名称小写加上_set来表示
默认返回的是一个querydict对象
自定义名称:person = models.ForeignKey(Person, related_name='person_set')
hBook = models.ForeignKey('BookInfo', \
related_name='person_set',\
on_delete=models.CASCADE)
用一访问一:对象.模型类小写
heroinfo.bookinfo
访问id:对象.属性_id
heroinfo.book_id
django 2.0,外键(ForeignKey)和一对一(OneToOneField),必须要写on_delete参数
否则会报异常:
TypeError: init() missing 1 required positional argument: 'on_delete'
on_delete参数的各个值的含义:
on_delete=None, # 删除关联表中的数据时,当前表与其关联的field的行为
on_delete=models.CASCADE, # 删除关联数据,与之关联也删除
on_delete=models.DO_NOTHING, # 删除关联数据,什么也不做
on_delete=models.PROTECT, # 删除关联数据,引发错误ProtectedError
on_delete=models.SET_NULL, # 删除关联数据,与之关联的值设置为null(前提FK字段
需要设置为可空,一对一同理)
on_delete=models.SET_DEFAULT, # 删除关联数据,与之关联的值设置为默认值(前提FK
字段需要设置默认值,一对一同理)
一对一
from django.db import models
# Create your models here.
#帐户
class Account(models.Model):
username = models.CharField(max_length=20,null=True)
password = models.CharField(max_length=20)
register_date = models.DateField(auto_now_add=True)
#联系人
class Concat(models.Model):
account = models.OneToOneField(Account,on_delete=models.CASCADE)
address = models.CharField(max_length=30)
mobile = models.CharField(max_length=11)
#黑窗口 操作
(envtest44) D:\test\vritualenv\envtest44\demo02>python manage.py shell
Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from one_to_one.models import Account,Concat
>>> from * import datetime
File "<console>", line 1
from * import datetime
^
SyntaxError: invalid syntax
>>> from datetime import *
>>> a = Account()
>>> a.username='Tom'
>>> a.password='123'
>>> a.save()
>>> c = Concat()
>>> c.account = a
>>> c.address = 'zz'
>>> c.save()
>>> print(c.account)
Account object (1)
>>> print(c.account.username)
Tom
>>> print(a.concat)
Concat object (1)
>>> print(a.concat.address)
zz
>>> exit()
多对多
from django.db import models
# Create your models here.
class Host(models.Model):
id = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=20)
class Application(models.Model):
name = models.CharField(max_length=20)
rat = models.ManyToManyField(to="Host")
# 黑窗口中检测
envtest44) D:\test\vritualenv\envtest44\demo02>python manage.py shell
Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from many_to_many.models import Host,Application
>>> a = Application(1,'qq')
>>> a.save()
>>> h1 = Host(hostname='host1')
>>> h1.save()
>>> h2 = Host(hostname='host2')
>>> h2.save()
>>> h3 = Host(hostname='host3')
>>> h3.save()
>>> a.rat.add(1)
>>> a.rat.add(2,3)
>>> a.rat.all()
<QuerySet [<Host: Host object (1)>, <Host: Host object (2)>, <Host: Host object (3)>]>
>>> h1.application_set.all()
<QuerySet [<Application: Application object (1)>]>
>>> a.rat.remove()
>>> a.rat.remove(1)
>>>
网友评论