文章目录
- 表结构
- 字段类型
- 参数约束
- 单表
- 表结构
- 数据的操作
- 增
- 查
- 改
- 删
- 多表 -- ForeignKey
- 表结构
- 查询
- 多表 -- ManyToManyField
- 表结构
- 查询
表结构
字段类型
字段 | 备注 |
AutoField | 自增列, 必须填入 primary_key=True, 如果没有该列, 会自动创建一个名为 id 的列 |
IntegerField | 10 位内数字 |
CharField | 字符串类型, 必须填如 manx_length 参数限制长度 |
DateField | YYYY-MM-DD, 相当于 datetime.date() |
DateTimeField | YYYY-MM-DD HH:MM:[:ss:[.uuuuuu]], 相当于 datetime.datetime() |
参数约束
参数 | 注释 |
null | 是否允许为空 |
unique | 是否唯一 |
db_index | 设置为索引 |
default | 设置默认值 |
auto_now_add=True | 记录创建时间 |
auto_now=True | 记录变更时间 |
单表
表结构
class Person(models.Model):
id = models.AutoField(primary_key=True) # id, 自增, 且为主键
name = models.CharField(max_length=16, null=False) # 姓名, 最大长度为 16, 不允许为空
age = models.IntegerField(null=True, blank=True) # 年龄, 数据库允许为空, admin 系统允许为空
phone = models.CharField(max_length=11, unique=True) # 电话, 唯一字段, 最大长度为 11 位
数据的操作
增
- 单独增
# 单独添加新的数据行
models.Publisher.objects.create(name="Gury", age=19, phone="1231231234")
- 批量增
# 先创建一个生成表达式
p_list = [ models.Publisher(name="xx-{}".format(i)) for i in range(100) ]
# 使用 bulk_create 方法批量创建
models.Publisher.objects.bulk_create(p_list)
查
- 基础查询
# 查询所有数据
models.Person.objects.all() # 返回 QuerySet<[obj, obj, ..]>
# 查询满足条件的
models.Person.objects.filter(id=1) # 返回 QuerySet< [obj, obj, ..]>
models.Person.objects.get(id=1) # 返回 obj, 谨慎使用!!
# 对结果进行字段筛选
models.Person.objects.all().values("name", "phone") # 返回 QuerySet< [{dic}, {dic}, ..]>, 结果需要使用["key"]取值
models.Person.objects.all().values_list("name", "phone") # 返回 QuerySet< [(tuple), (tuple), ..]>, 结果需要使用[index]取值
# 查询不满足条件的
models.Person.objects.exclude(id=1) # 返回 QuerySet< [obj, obj, ..]>
# 查询结果排序
models.Person.objects.all().order_by("id") # 返回 QuerySet< [obj, obj, ..]>,
models.Person.objects.all().order_by("id").reverse() # 将 order_by 的结果反序
# 数据条数
models.Person.objects.all().count() # 返回 int
# 取头/尾数据
models.Person.objects.all().first() # 返回 object
models.Person.objects.all().last()
# 判断是否存在
models.Person.objects.filter(id=1).exists() # 返回 Bool
# 去重
distinct() # 常用于跨表查询去重, mysql 不支持按照字段去重
- 进阶查询(双下划线用法)
# 数字比较
models.Person.objects.filter(id__gt=1) # __gt 大于
models.Person.objects.filter(id__lt=2) # __lt 小于
models.Person.objects.filter(id__gte=1) # __gte 大于等于
models.Person.objects.filter(id__lte=2) # __lte 小于等于
# 数字包含
models.Person.objects.filter(id__in=[1,3]) # id 在列表中
models.Person.objects.exclude(id__in=[1,2]) # id 不在列表中
# 字符串包含
models.Person.objects.filter(name__contains="t") # 包含字母 t 的
models.Person.objects.filter(name__icontains="T") # 忽略大小写包含
# 范围内
models.Person.objects.filter(id__range=[1,4]) # id 为 1 到 4 的
# 开头, 结尾
models.Person.objects.filter(name__startswith="T") # 以 "T" 开头
models.Person.objects.filter(name__endswith="m") # 以 "m" 结尾
# 日期格式年月日为特定值
models.Person.objects.filter(birthday__year=2018) # __year, __month, __day
改
# 先查询, 拿到需要修改的对象, 再做操作
obj = models.Person.objects.get(id=1)
# 若数据为单独的, 可直接给属性赋值
obj.name = "new_name"
# 若数据为列表, 使用 set() 重新设置值
obj.books.set([1, 2, 3]) # obj.属性.set([])
# 为列表数据添加值
obj.books.add(4) # obj.属性.add()
# 提交给数据库
obj.save()
删
# 先查询, 再使用 delete() 删除
models.Publisher.objects.get(id=1).delete()
多表 – ForeignKey
表结构
"""
一个 Leader 领导多个 Staff
leader -- 基础表 -- "一"
staff -- 外键表 -- "多"
"""
class Leader(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=15)
def __str__(self):
return self.name
class Staff(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=15)
leader = models.ForeignKey(to=Leader, on_delete=models.CASCADE)
def __str__(self):
return self.name
查询
- 基于 obj , 外键表查基础表
# 1. 查询外键表, 拿到 obj
obj = models.Staff.objects.get(id=1)
# 2. obj.基础表.查询字段, 拿到唯一的结果
r = obj.leader.name
- 基于 obj, 基础表查外键表(外键表_set 的使用)
# 1. 查询基础表, 拿到 obj
obj = models.Leader.objects.get(id=1)
# 2. obj.外键表_set.all(), 拿到 qs
qs = obj.staff_set.all()
# 3. qs.values_list("查询字段")
r = qs.values_list("name")
- 基于 QuerySet, 外键表查基础表
# 1. 查询外键表, 拿到 qs
qs = models.Staff.objects.filter(id=1)
# 2. qs.values_list("基础表__查询字段")
r = qs.values_list("leader__name")
- 基于 QuerySet, 基础表查外键表(用法与基于 QuerySet, 外键表查基础表相同)
# 1. 查基础表, 拿到 qs
qs = models.Leader.objects.filter(id=1)
# 2. qs.values_list("外键表__查询字段")
r = qs.values_list("staff__name")
多表 – ManyToManyField
表结构
class Leader(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=15)
def __str__(self):
return self.name
class Staff(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=15)
# related_name, 基于 qs, 基础表查外键表时使用
leader = models.ManyToManyField(to=Leader, related_name="yuangong")
def __str__(self):
return self.name
查询
- 基于 obj, 外键表查基础表
# 1. 查询外键表, 拿到 obj
obj = models.Staff.objects.first()
# 2. obj.基础表.all(), 拿到 qs
qs = obj.leader.all()
# 3. qs.values_list("查询字段")
r = qs.values_list("name")
- 基于 obj, 基础表查询外键表(用法与基于 obj, 外键表查基础表相同)
# 1. 查询基础表, 拿到 obj
obj = models.Leader.objects.first()
# 2. obj.基础表.all(), 拿到 qs
qs = obj.staff.all()
# 3. qs.values_list("查询字段")
r = qs.values_list("name")
- 基于 QuerySet, 外键表查基础表(通过 to 参数)
# 1. 查询外键表, 拿到 qs
qs = models.Staff.objects.filter(id=1)
# 2. qs.values_list("基础表__字段")
r = qs.values_list("leader__name")
- 基于 QuerySet, 基础表查外键表(通过 related_name 参数)
# 1. 查询基础表, 拿到 qs
qs = models.Leader.objects.filter(id=1)
# 2. qs.values_list("related_name__字段")
r = qs.values_list("yuangong__name")