模型
模型是基于ORM设计思想
ORM (对象关系映射)
- 类与表的关系
- 对象与记录的关系
- 属性与字段的关系
模型类的定义
- 在 应用下的 models.py 文件中定义模型类
class Student(models.Model):
pass
模型中常见的属性类型
-
CharField varchar
- EmailField varchar
-
FileField varchar
- ImageField varchar
-
TextField longtext
-
BinaryField longblob
-
IntegerField int
- BigIntegerField bigint
- SmallIntegerField smallint
-
AutoField int
-
FloatField float/double
-
DecimalField decimal
-
DateField date
-
DateTimeField datetime
-
TimeField time
-
BooleanField boolean
-
OneToOneField
-
ForeignKey
-
ManyToManyField
属性类 Field 中的属性
属性名 | 说明 | 默认值 |
---|---|---|
verbose_name | 属性的标签名、影响的是 admin站点网页 | None |
name | 设置属性名、name会修改属性的名称, 不常用 | None |
primary_key | 设置属性是否是主键、影响数据库 | False |
max_digits | 针对字符串、设置最大长度 | None |
unique | 设置属性是否唯一,影响数据库 | False |
blank | 设置属性是否为空、影响网页校验效果 | False |
null | 设置属性是否为空,影响的是数据库 | False |
default | 设置属性的默认值、影响数据库 | NOT_PROVIDED |
editable | 是否允许修改、影响网页 | True |
choices | 设置值的选项、对应一个下拉列表效果 | None |
help_text | 帮助文本、属性的提示信息、影响网页效果 | None |
db_column | 设置属性对应的数据库字段名、默认值和属性名保持一致 | 属性名 |
auto_created | 设置属性是否自动增长、一般配合主键使用 | False |
validators | 设置属性的校验规则 | None |
error_messages | 校验失败的提示信息 | None |
FileField 特有的属性
属性名 | 属性描述 | 默认值 |
---|---|---|
upload_to | 设置文件上传的存储位置 | 空字符串 |
storage | 设置上传文件的存储引擎 | None |
DecimalField 特有的属性
属性名 | 属性描述 | 默认值 |
---|---|---|
max_digits | 最大有效数字的位数 | None |
decimal_places | 小数点后保留几位小数 | None |
DateField 特有的属性
属性名 | 属性描述 | 默认值 |
---|---|---|
auto_now | 设置是否采用当前系统时间作为属性的值 | False |
关系属性类 常见的属性
属性名 | 属性描述 | 默认值 | 是否必传 | 备注 |
---|---|---|---|---|
to | 设置关系属性指向的模型类、如果指向自己,使用 “self” | Y | ||
on_delete | 指定当删除数据的时候,时候级联删除父数据 | models.DO_NOTHING models.CASCADE | Y | |
null | 是否允许为空 | N | 推荐使用 null=True | |
blank | 页面是否必传 | N | 推荐使用 blank=True | |
related_name | 在关系方维护自己的属性 | N |
模型类的完整定义
class Student(models.Model):
"""
一个模型类、对应数据库的一张表, 表名 默认是 应用名_模型名
django中的模型 会自动生成一个 主键 且 属性名为 id,
如果模型中自己定义了主键、则 django 不在自动生成 id主键
"""
name = models.CharField(max_length=100, verbose_name="学生名", blank=False, null=True)
# choices 是一个 二维元组, ('m', '男') ==> 数据库存放的是 m , 页面显示的是 男
# choices 对应页面的下拉列表 <select> <option value="m">男</option><option value="f">女</option></select>
sex = models.CharField(max_length=1, verbose_name="性别", default="m", choices=(("m", "男"), ("f", "女")))
birth = models.DateField(verbose_name="出生日期", null=True, blank=True, db_column="birthday")
tel = models.CharField(max_length=11, verbose_name="手机号", null=True, blank=True)
email = models.EmailField(verbose_name="邮箱", null=True, blank=True)
# auto_now 如果为 true, 新增、修改 都会改变这个值并且取当前系统时间, 默认值default 只影响插入
create_time = models.DateTimeField(default=timezone.now, verbose_name="入学时间")
score = models.FloatField(null=True, blank=True)
class Meta:
# 指定模型类对应的表名,默认是应用名_模型名
db_table = "t_student"
django数据迁移 (通过模型自动生成对应的表)
- 检查应用下的模型是否 存在异常
python manage.py check appName
- 生成建表需要的迁移文件
python manage.py makemigrations appName
- 查看迁移文件对应的 SQL语句
python manage.py sqlmigrate appName 迁移文件的编号
- 执行迁移文件、维护相关的表
# 生成django项目所有的应用下的所有模型对应的表
python manage.py migrate
# 只执行 appName 应用下的迁移文件
python manage.py migrate appName
django shell
python manage.py shell
模型 - 数据新增
- 方式一:
from user.models import Student
stu = Student(name='xxxx', sex='f', ....)
stu.save()
- 方式二:
# 返回一个模型管理器
manage = Student.objects
stu = manage.create(name=xxxx, sex="", ...)
============================================
stu = Student.objects.create(...)
模型 - 数据的修改
- 方式一 :
stu = Student(id=1, name="xxx", sex="f")
stu.save()
===============================================================
stu = Student.objects.get(pk=1)
stu.name = 'xxx'
stu.sex = 'f'
stu.save()
PS: save方法可以实现数据的新增和修改、如果 主键不存在 或者 主键存在,但数据库中找不到对应的记录,则 新增, 否则 修改
save 方法在做数据修改的时候,采用的是 表中全字段修改
- 方式二:
queryset = Student.objects.filter(pk=1)
queryset.update(name='xxx', sex='xxx')
模型-数据的删除
- 模型对象 调用 delete 删除数据
Student.objects.get(pk=1).delete()
- queryset 对象调用 delete 删除数据
Student.objects.filter(pk=1).delete()
模型-数据的查询
- 模型管理器 Model.objects
模型管理器/QuerySet 常见的方法
- get()
- filter() : 相当于 where
- exclude() : 相当于 not filter
- all()
- values()
- order_by()
- first()
- last()
- count()
- distinct()
get([条件]) 方法
- 获取有且只有一条数据、返回 模型对象
Student.objects.get() : 如果表中查过一条、则抛出 MultipleObjectsReturned
如果表中没有数据、则抛出DoesNotExist
filter([条件]) 方法
- 对表中的数据进行筛选过滤、相当于数据库中的 where, filter 返回 QuerySet 对象
Student.objects.filter(pk=1)
--
select * from t_student where id = 1
exclude([条件]) 方法
- 对表中的数据进行筛选过滤、排除满足条件的数组、返回 QuerySet对象
Student.objects.exclude(pk=1)
-- 相当于 mysql
select * from t_student where id != 1
all() 方法
- 查询所有数据、返回QuerySet 对象
Student.objects.all()
values(prop…) 方法
- values 查询到的数据、返回 QuerySet对象
- values 查询到的每一条记录,是一个字典格式的数据
- values 可以查询部分属性
Student.objects.values("id", "name")
order_by(prop…) 方法
- 对查询的结果进行排序
- 多个排序用逗号分割
- 默认采用升序排列,如果要使用降序排列,在 属性的前面加
-
即可
-- 按照 name 升序排列
Student.objects.order_by("name")
-- 按照 name 降序排列
Student.objects.order_by("-name")
distinct() 去重
- 配合value方法,对查询到数据进行去重
Student.objects.values("sex").distinct()
查询条件
- 关系条件查询
- 逻辑条件查询
- 模糊查询
- 区间查询
- 枚举查询
- 空值查询
- 日期查询
关系条件查询
- __gt= 大于
- __gte= 大于等于
- __lt= 小于
- __lte= 小于等于
- = 等于
- __exact= 等于
- __iexact= 等于(忽略大小写)
# 查询成绩大于 50分 的学生
select * from t_student where score > 50 ;
Student.objects.filter(score__gt=50)
逻辑条件查询
# 查询成绩 大于 50 且 性别为 男的所有学生
select * from t_student where score > 50 and sex = 'm'
Student.objects.filter(score__gt=50, sex='m')
-- 使用 Q 查询、完成 and 逻辑与
from django.db.models import Q
Student.objects.filter(Q(score__gt=50) & Q(sex='m') )
# 查询 成绩大于 50 或者 性别为 男 的学生
select * from t_student where score > 50 or sex = 'm'
Student.objects.filter( Q(score__gt=50) | Q(sex__exact='m') )
模糊查询
-
__startswith= 以 … 开头
-
__endswith= 以 … 结尾
-
__contains= 包含…
-
__istartswith= 以 … 开头,忽略大小写
-
__iendswith= 以 … 结尾,忽略大小写
-
__icontains= 包含…,忽略大小写
# 查询 名字包含 a 的所有学生
select * from t_student where name like '%a%'
Student.objects.filter(name__contains="a")
区间查询
- __range=(min, max)
# 查询 成绩在 60 -80 之间的所有学生
select * from t_student where score between 60 and 80 ;
Student.objects.filter(score__range=(60, 80))
枚举查询
- __in=(val, …)
查询 id 为 1,3 ,5 的所有学生
select * from t_student where id in (1, 3, 5)
Student.objects.filter(pk__in=(1,3,5))
空值查询
- __isnull=True/False
查询 生日 为空的学生信息
select * from t_student where birthday is null ;
Student.objects.filter(birth__isnull=True)
日期条件查询
- __date= : 根据日期查询
- __year= : 根据年份查询
- __month= : 根据月份查询
- __day= : 根据 天查询
- __hour= : 根据小时查询
- __minute= 根据分钟查询
- __second= 根据秒查询
Student.objects.filter(create_time__date="2020-09-10")
F 对象
- 对模型属性的引用
-- 将ID=1 的学生成绩增加 40 分
Student.objects.filter(pk=1).update(score= F("score") + 40)
- 控制排序
-- 按照成绩升序排列、没有成绩的显示在末尾
Student.objects.order_by(F("score").asc(nulls_last=True))
F 对象中,有 asc 和 desc 两个方法实现 基于某个属性的排序
asc , desc 两个函数都可以 设置两个属性
nulls_last : 空值是否显示在最后
nulls_first: 空值是否现在在前面
annotate 配合 values 完成分组效果
from django.db.models import Sum. Avg, Max, Min , Count
-- 查询男生、女生对应的人数
Student.objects.values("sex").annotate(count=Count("sex"))
aggregate 聚合操作
-- 查询学生中成绩最高的分数
Student.objects.aggregate(max=Max("score"))
Func 对象
from django.db.models import Func
Student.objects.values("name", md5=Func(F("name"), function="md5"))
---
select name, md5(name) as md5 from t_student
from django.db.models import Value
Student.objects.create(name=Func(Value("abc"), function="md5"), sex="m")
Student.objects.values(namex = Func(F("name"), 1 , 2 , function="substring"))
Django 内置的 User 模型
from django.contrib.auth.models import User
User模型常见的属性
- username : 用户名
- password : 密码,采用了加密技术
- last_login : 最近登录的时间
- is_superuser : 是否是超级用户
- first_name : 名
- last_name : 姓
- email : 邮箱
- is_staff : 是否允许进入后台 admin 站点
- is_active : 是否激活
- date_joined : 用户的注册时间
User模型对应的管理器常见的方法
- create_user(username, password, email, **extra_fields) : 创建一个普通用户、密码自动加密、并返回 user对象
- create_superuser() : 创建一个超级用户、密码自动加密
- set_password() : 将明文密码 设置成密码,并赋值 给 user的 password 属性
- check_password() : 校验密码
自定义模型管理器
class StudentManage(models.Manage):
def create_stu(**kwargs):
model = self.model(**kwargs)
model.save()
return model ;
class Student(models.Model):
...
objects = StudentManage()
解决模型录入时间差8小时问题
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
模型的逆向工程
- 通过 表 创建 模型
python manage.py inspectdb 表