ORM 对象关系映射
功能:根据对象的类型生成表结构,
将表结构转换为数据库语句,将数据库结果转换为对象或者表
优点:极大的简化了编程人员的工作量,统一了代码编写。
模型、属性和表、字段间的关系:一个模型对应一张表,该模型中的属性对应该模型表的字段
注意:django会自动的给每一张表设定主键,当人为的设定逐渐后django就不会添加主键
属性的命名规则:python的关键字标识符,连续的下划线不可以为属性名称
使用流程
库的导入
django中定义的属性和模型都存放在django.db.models.files的目录下,伪类方便使用
被导入到django.db.models中
使用方式:from django.db import models
数据的逻辑删除
对于重要的数据我们一般定义逻辑删除,定义字段isdelete,默认属性为False
字段类型
AutoField 一个自动增加的整数类型字段。通常你不需要自己编写它,
Django会自动帮你添加字段:id = models.AutoField(primary_key=True),
这是一个自增字段,从1开始计数。如果你非要自己设置主键,
那么请务必将字段设置为primary_key=True。
Django在一个模型中只允许有一个自增字段,并且该字段必须为主键!
BigAutoField (1.10新增)64位整数类型自增字段,数字范围更大,从1到9223372036854775807
ForeignKey 外键,关联其他的表
CharField(max_length= n) 字符串字段,可以设定最大长度。表单textinput类型
TextField 大量文本内容,在HTML中表现为Textarea标签,最常用的字段类型之一!
如果你为它设置一个max_length参数,那么在前端页面中会受到输入字符数量限制,
然而在模型和数据库层面却不受影响。只有CharField才能同时作用于两者。
IntegerField
整数类型,最常用的字段之一。取值范围-2147483648到2147483647。在HTML中表现为NumberInput标签。
DecimalField
固定精度的十进制小数。相当于Python的Decimal实例,必须提供两个指定的参数!参数max_digits:数值最大的总位数,
必须大于或等于小数点位数 。decimal_places:小数点位数,精度。 当localize=False时,它在HTML表现NumberInput标签,
否则是text类型。例子:储存最大不超过999,带有2位小数位精度的数,
定义如下:models.DecimalField(…, max_digits=5, decimal_places=2)。
FloatField
浮点数类型,参考整数类型
BooleanField
布尔值类型。在HTML表单中体现为CheckboxInput标签。如果要接收null值,
请使用NullBooleanField。
NullBooleanField
类似布尔字段,只不过额外允许NULL作为选项之一。
DateField
class DateField(auto_now=False, auto_now_add=False, **options)日期类型。
一个Python中的datetime.date的实例。在HTML中表现为TextInput标签。在admin后台中,
Django会帮你自动添加一个JS的日历表和一个“Today”快捷方式,以及附加的日期合法性验证。
两个重要参数:(参数互斥,不能共存) auto_now:每当对象被保存时将字段设为当前日期,
常用于保存最后修改时间。auto_now_add:每当对象被创建时,设为当前日期,常用于保存创建日期(注意,它是不可修改的)。
设置上面两个参数就相当于给field添加了editable=False和blank=True属性。如果想具有修改属性,请用default参数。
例子:pub_time = models.DateField(auto_now_add=True),自动添加发布时间。
TimeField
时间字段,Python中datetime.time的实例。接收同DateField一样的参数,只作用于小时、分和秒。
DateTimeField
日期时间类型。Python的datetime.datetime的实例。与DateField相比就是多了小时、分和秒的显示,
其它功能、参数、用法、默认值等等都一样。
FileField
class FileField(upload_to=None, max_length=100, **options)上传文件类型,后面单独介绍。
ImageField
图像类型
FilePathField
文件路径类型
class MyModel(models.Model):
# 文件被传至`MEDIA_ROOT/uploads`目录,MEDIA_ROOT由你在settings文件中设置
upload = models.FileField(upload_to=’uploads/’)
# 或者
# 被传到`MEDIA_ROOT/uploads/2015/01/30`目录,增加了一个时间划分
upload = models.FileField(upload_to=’uploads/%Y/%m/%d/’)
使用FileField或者ImageField字段的步骤:
在settings文件中,配置MEDIA_ROOT,作为你上传文件在服务器中的基本路径(为了性能考虑,这些文件不会被储存在数据库中)。
再配置个MEDIA_URL,作为公用URL,指向上传文件的基本路径。请确保Web服务器的用户账号对该目录具有写的权限。
添加FileField或者ImageField字段到你的模型中,定义好upload_to参数,文件最终会放在MEDIA_ROOT目录的“upload_to”子目录中。
所有真正被保存在数据库中的,只是指向你上传文件路径的字符串而已。可以通过url属性,在Django的模板中方便的访问这些文件。
例如,假设你有一个ImageField字段,名叫mug_shot,那么在Django模板的HTML文件中,可以使用{
{ object.mug_shot.url }}
来获取该文件。其中的object用你具体的对象名称代替。
可以通过name和size属性,获取文件的名称和大小信息。
安全建议
无论你如何保存上传的文件,一定要注意他们的内容和格式,避免安全漏洞!务必对所有的上传文件进行安全检查,
确保它们不出问题!如果你不加任何检查就盲目的让任何人上传文件到你的服务器文档根目录内,比如上传了一个CGI或者PHP脚本,
很可能就会被访问的用户执行,这具有致命的危害。
GenericIPAddressField
class GenericIPAddressField(protocol=’both’, unpack_ipv4=False, **options)[source],IPV4或者IPV6地址,
字符串形式,例如192.0.2.30或者2a02:42fe::4在HTML中表现为TextInput标签。
参数protocol默认值为‘both’,可选‘IPv4’或者‘IPv6’,表示你的IP地址类型。
PositiveIntegerField
正整数字段,包含0,最大2147483647。
PositiveSmallIntegerField
较小的正整数字段,从0到32767。
SlugField
slug是一个新闻行业的术语。一个slug就是一个某种东西的简短标签,包含字母、数字、下划线或者连接线,
通常用于URLs中。可以设置max_length参数,默认为50。
SmallIntegerField
小整数,包含-32768到32767。
URLField
一个用于保存URL地址的字符串类型,默认最大长度200。
UUIDField
用于保存通用唯一识别码(Universally Unique Identifier)的字段。使用Python的UUID类。
在PostgreSQL数据库中保存为uuid类型,
其它数据库中为char(32)。这个字段是自增主键的最佳替代品。
字段选项
null= 为True 空值,储存到数据库中null 默认值False
blank= 为True,允许空白默认值为false
db_column= string更改属性在数据表中的名称
db_index= True添加一个索引
default 默认值
primary_key 主键
unique 唯一值,不可相同
关系
ForeignKey 一对多关系,定义在多的一方
ManyToManyField 多对多关系,定义在第三方表
OneToOneField 一对一关系,定义在任意一方即可
一访问多
对象名.小写模型名_set
grades.students_set
一访问一
对象名.小写模型名
grades.student
访问id值
对象名.属性_id
grades.students_id
元类选项
定义class Meta:
类定义属性db_table = string 更改表名
排序属性ordering = [‘id’] 默认为升序 -id为降序
注意:ordering会增加数据库的开销
模型成员之管理器
类属性 objects 是一个manager对象与数据库交互数据
当没有定义管理器的时候django会为模型添加objects管理器
自定义管理器:
定义后django就不会创建objects对象
stuobj = models.Manager()
作用:
1.添加新的方法
2.修改原始查询数据,重写get_queryset()方法
# 重写模型管理器对象方法
class StudentManager(models.Manager):
# 重新定义查询函数,保留isdelete=false的数据
def get_queryset(self):
return super(StudentManager, self).get_queryset().\
filter(isdelete= False)
class Students(models.Model):
# 创建stuobj管理器
stuobj = models.Manager()
stuobj2 = StudentManager()
创建对象
功能:向数据库中添加数据,创建对象不会向数据库添加数据,调用save()才会添加数据
__init__在父类models.Model中使用,自定义对象不可使用
创建方法
模型中添加一个类方法
# 创建类方法,添加类数据
@classmethod
def createStudent(cls, sname, sage, sgender, sbirth, sgrade, isdelete= False):
stu = cls(name= sname, age= sage, gender= sgender, birth= sbirth,
grade= sgrade, isdelete= isdelete)
stu.save()
再到views.py文件中定义相关的功能函数
# 调用类方法添加属性
def addstudent(myrequest):
grade = Grades.objects.get(pk= 1)
Students.createStudent(‘lilei’,20,True,’1989-11-15 08:30:33′, grade)
return HttpResponse(“Successfully !”)
定义管理器中添加一个方法
# 重写模型管理器对象
class StudentManager(models.Manager):
# 重新定义查询函数,保留isdelete=false的数据
def get_queryset(self):
return super(StudentManager, self).get_queryset().\
filter(isdelete= False)
def createStudent(self, sname, sage, sgender, sbirth, sgrade, isdelete=False):
# 创建模型对象
stu = self.model()
stu.age = sage
stu.name = sname
stu.birth = sbirth
stu.gender = sgender
stu.grade = sgrade
stu.isdelete = isdelete
stu.save()
查询模型
功能:对数据库中的数据进行田间查询,查询器可以有多个过滤器
查询基函数方法:
all()
获取全部的数据集合对象
filter()
获取复合条件的数据集合
filter(键=值)
filter(键=值, 键=值)
filter(键=值).filter(键=值)
exclude()
过滤掉复合条件的数据集
order_by()
排序
values()
返回字典为元素的列表,每个字典包含一个对象数据
单个数据返回的函数:
get() 没找到数据或者找到多个数据都会发生异常
count() 返回查询集的对象个数
first() 返回查询集的第一个对象
last() 返回查询集的最后一个对象
exists() 返回布尔值,判断数据集中是否有数据对象
返回有限的数据集数据对象
由于数据集合是由列表展现在出来的,所以可以用角标提取[a:b],角标不可用负数。
查询集的缓存概念:每次的查询都会保留缓存,除了第一次为空,是为了提高查询的效率
逻辑查询字段
相当于filter,exclude,get等函数的参数
语法: 属性名__比较运算符=值 双下划线
外键: 属性名_id=值
转义: % _ 等特殊符号直接被转义为一般符号
比较运算符:
exact 判断 filter(isdelete=False)大小写敏感
contains 包含 students.stuobj2.fliter(name__contain=’sun’)
startswith和endswith 以什么卡头或结尾 students.stuobj2.fliter(name__startswith=’sun’)
前面加上i就不存在大小写敏感 iexact, icontains,istartswith, iendswith
isnull isnotnull 是否为空 filter(name__isnull= False)
in 是否在指定的范围内 students.stuobj2.filter(pk__in= [2,4,6,8,10])
gt,gte,lt,lte 大于,大于等于,小于,小于等于
year,month,day,week_day,hour,minute,second时间上的判断
聚合函数
使用aggregate()函数返回聚合函数的值
Max
Min
Sum
Avg
Count
from django.db.model import Max
# 返回最大的年龄数值
Students.stuobj2.aggregate(Max(‘age’))
F对象 对象内部属性值的相互比较
from django.db.models import F,Q
#F对象的使用,模型内部的属性值间的比较,查询男生小于女生的班级
# stu = Grades.objects.filter(girlsnum__gt= F(‘boysnum’))
# F对象的数学运算使用
stu = Grades.objects.filter(girlsnum__gte= F(‘boysnum’) + 20)
Q对象 用于对象内部属性值间的或比较需求
# 选择班级为1和2的学生
stu = Students.stuobj2.filter(Q(grade= 1) | Q(grade= 2))
# 选择班级不为1的学生
stu = Students.stuobj2.filter(~Q(grade= 1))
跨关联查询
# 在班级表中查询学生名字有Lucy的班级
stu = Grades.objects.filter(students__name__contains= ‘lucy’)