ORM 操作

什么是ORM

全称 Object Relational Mapping, 对象关系映射

    类        -->      数据表
    属性      -->      字段
    对象      -->      数据行

使用ORM和sql连接数据库的区别

  • ORM

    不用自己写sql语句
    外键查询方便
    执行效率不高(需要先将orm转化为sql)
    
  • sql语句

    需要自己写sql
    执行效率高
    

使用ORM

Django中连接数据库的配置

  • settings.py
"""
数据库相关配置
"""

DATABASES = {
    'default': {
        # 使用sqlit3
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

        # 使用mysql
        # 'ENGINE': 'django.db.backends.mysql',
        # 'NAME': 'yky',
        # 'HOST': '47.92.26.160',
        # 'PORT': 3456,
        # 'USER': 'root',
        # 'PASSWORD': 'Byyhyy1234!',
    }
}
  • __init__.py
"""
将默认的mysqldb模块改为pymysql模块
使用pymysql模块连接数据库
"""

import pymysql
pymysql.install_as_MySQLdb()

操作数据表(表结构)

  • models.py
"""
django会在person前添加"appName_"
创建appName_person表
"""

class Person(models.Model):
    id = models.AutoField(primary_key=True) # 主键
    name = models.CharField(max_length=32) # 最大长度32
    age = models.IntegerField() # 最大长度为10

"""
unique = True # 唯一
null = True # 可以为空 
blank = True # 允许django admin操作为空
"""
  • 常用字段
# 字符串类型
CharField

# 自增类型
AutoField

# 时间类型
DateField
DateTimeField()
TimeField()

IntergeField()
  • 常用参数
# 可以为空
null=True

# 默认值为0
default=0

# 唯一
unique=True

# 时间字段中,自动更新   
auto_now_add=True    第一次创建时, 更新该字段
auto_add=True        每次数据被修改时, 更新该字段 
  • 执行命令
# 将变化都记录下来
python manage.py makemigrations

# 转换为sql语句执行
python manage.py migrate

操作数据内容

单表

增加

"""
向Person表中添加name为u1, age为16的数据
"""

models.Person.objects.create(name='u1', age=16)

删除

"""
删除name为u1的数据
"""

models.Person.objects.get(name='u1').delete()

修改

"""
先找到对应数据, 保存为对象
修改对象的属性
同步到数据库
"""

obj = models.Person.objects.get(name='u1')
obj.name = 'new_u1'
obj.save()

查询

普通方法
"""
1. 查询
"""
# 所有结果
models.Person.objects.all()

"""
2. 根据条件查询
"""
# 常用, 返回一个QuerySet列表
models.Person.objects.filter(id=2) 
# 根据查询条件获取一个唯一的值, 不唯一或者无匹配都会报错, 慎用 
models.Person.objects.get(id=2) 

"""
3. 返回查询结果的多个字段
"""
# 返回一个QuerySet,里面是字典
models.Person.objects.filter(id=2).values('name','age')
# 返回一个QuerySet,里面是元祖
models.Person.objects.filter(id=2).values_list('name','age')

"""
4. 返回第一个或最后一个
"""
# 取第一个数据
models.Person.objects.filter(id=2).first() 
# 取最后一个数据
models.Person.objects.filter(id=2).last()

"""
5. 对查询结果做处理
"""
# 将符合条件的都剔除掉,留下不符合条件的
models.Person.objects.filter(age=18).exclude(id=10)
# 对查询结果排序
models.Person.objects.filter(age=18).order_by('age')
# 对一个有序的查询结果集做反转
models.Person.objects.filter(age=18).reverse()
# 去重,跨表查询时去掉重复的记录,MySQL不支持按字段去重
models.Person.objects.filter(age=18).distinct()

"""
6. 返回查询信息
"""
# 返回数据条数
models.Person.objects.filter(age=18).count()
# 判断数据是否存在
models.Person.objects.filter(age=18).exists()   

分类:
返回QuerySet列表
all(), filter(), exclude()
order_by(), reverse(), distinct()

values(), values_list()
返回具体对象
first(), last(), get()
返回数字
count()
返回布尔值
exists()

进阶方法 - 单表的双下划线
# id小于10, 大于1
models.Person.objects.filter(id__lt=10, id__gt=1)

# 获取id等于11、22、33的数据
models.Person.objects.filter(id__in=[11, 22, 33])   
# not in
models.Person.objects.exclude(id__in=[11, 22, 33])

# 获取name字段包含"ven"的
models.Person.objects.filter(name__contains="ven") 
# 不区分大小写
models.Person.objects.filter(name__icontains="ven")

# id范围是1到3的,类似于sql中的"bettwen 1 and 3"
models.Person.objects.filter(id__range=[1, 3])   

# startwith, endwith
models.Person.objects.filter(name__startwith='张')

# date字段, birthday字段, 2018年的结果
models.Person.objects.filter(birthday__year=2018)

外键

一对多的关系, 通常外键建在"多"的一方

表结构

  • models.py
"""
一个学校中有很多学生
所以外键在Person表建立
"""

class Person(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField(max_length=3)
    # 级联删除, 2.0后需要手动指出, 1.11默认为此设置
    school = models.ForeignKey(to="School", on_delete=models.CASCADE)


class School(models.Model):
    name = models.CharField(max_length=32)```

外键查询

基于对象的正向查询
# 找到查询对象
person_obj = models.Person.objects.first()

# 对象.外键字段.查询字段
school_name = person_obj.school.name
基于QuerySet的正向查询(双下划线正向查询)
# 得到一个QuerySet
qs = models.Person.objects.all()

# 使用 "外键字段__查询字段"
ret = qs.values_list("school__name")

基于对象的反向查询
# 找到查询对象
school_obj = models.School.objects.get(id=2)

# 对象.查询表名_set
ret = school_obj.person_set.all()
基于QuerySet的反向查询(双下划线反向查询)
# 得到QuerySet
qs = models.School.objects.filter(id=1)

# 使用 "查询表__查询字段"
ret = qs.values_list("book__name")

多对多

一个人可以会很多种语言, 一种语言也有很多人会
"多对多的关系"

表结构

class Person(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    school = models.ForeignKey(to="School", on_delete=models.CASCADE)
    language = models.ManyToManyField(to="Language", related_name='ooo')


class School(models.Model):
    name = models.CharField(max_length=32)


class Language(models.Model):
    name = models.CharField(max_length=32)

多对多查询

基于对象的正向查询
# 获取正向查询对象
person_obj = models.Person.objects.first()

# 对象.多对多的字段, 结果为QuerySet
data = person_obj.language

# 再使用values()/values_list()/all()处理QuerySet
ret = data.values_list('name')
ret = data.all()
基于QuerySet的正向查询
# 获取QuerySet
data = models.Person.objects.filter(id=1)

# 处理QuerySet, "查询表__查询字段"
ret = data.values('language__name')

基于对象的反向查询
# 获取反向查询对象
language_obj = models.Language.objects.last()

# 对象.表名_set, 结果为QuerySet
ret = language_obj.person_set

# 如果models中设置了related_name属性(related_name设定为ooo)
ret = language_obj.ooo

# 最后使用values()/values_list()/all()做处理
ret = data.values_list('name')
ret = data.all()
基于QuerySet的反向查询
# 获取QuerySet
data = models.Language.objects.filter(id=1)

# 处理QuerySet, "related_name__查询字段"
ret = data.values('ooo__name')

增加

当form表单提交的数据是列表(多选的select/多选的checkbox)时
使用request.POST.getlist("hobby")
# 参数是一个列表, 重新赋值
.set([i1, i2, i3]) 

# 参数是一个值, 添加新值
.add(i4)
"""
用户提交了
    username = u1
    language = ['英语','日语']
"""

# 先创建对象
user_obj = models.Person.objects.create(name=username)
# 设置对象
user_obj.language.set(language)

猜你喜欢

转载自blog.csdn.net/yang_kaiyue/article/details/81875779