0
点赞
收藏
分享

微信扫一扫

Django 之 ORM



文章目录

  • 表结构
  • 字段类型
  • 参数约束
  • 单表
  • 表结构
  • 数据的操作
  • 多表 -- 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")



举报

相关推荐

0 条评论