我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Django之ORM

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Django之ORM

ORM即Object Relational Mapping(对象关系映射)
对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换 。从效果上说,它其实是创建了一个可在编程语言里使用的—“虚拟对象数据库”。

在Django中具体的对应方式为:

  • 类名对应数据库中的表名
  • 类名对应数据库中的表名
  • 类属性对应数据库里的字段
  • 类实例对应数据库表里的一行数据
  • 类实例对象的属性对应这行中的字段的值

Django默认使用的是sqlite,如果想使用mysql来存储数据,需要改变成相应的数据库引擎,具体如下:

1.修改setting文件


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

改成


DATABASES = {
      'default': {
      'ENGINE': 'django.db.backends.mysql',
      'NAME':'mysite',
      'USER': 'root',
      'PASSWORD': '000000',
      'HOST': '127.0.0.1',
      'PORT': '3306',
    }
}
2.引入pymysql驱动

init.py文件中加上


import pymysql pymysql.install_as_MySQLdb()

1.一个简单的创建

数据库表的创建在ORM中就是类的创建。


class student(models.Model):
    name=models.CharField(max_length=20)
    num=models.IntegerField()
    school=models.ForeignKey(school,on_delete=models.CASCADE)
    teacher=models.ManyToManyField(teacher)
    def __str__(self):
        return self.name

class school(models.Model):
    name = models.CharField(max_length=20)
    def __str__(self):
        return self.name

class teacher(models.Model):
    name = models.CharField(max_length=20)
    def __str__(self):
        return self.name

首先在models.py中简单的创建了三个表,然后需要在当前项目有manage.py文件目录下的cmd或者pycharm中的terminal下执行如下命令来同步数据库:

python manage.py makemigrations  #为模型改变生成迁移文件
python manage.py migrate    #应用数据库迁移

这时在数据库中就会显示有这3张表了

2.字段的类型与参数

几个常用的类型:

  • CharField
  • IntegerField
  • TextField
  • 等等

几个常用的参数:

  • null
  • default
  • primary_key
  • unique
  • 等等

具体参考Django官方文档https://docs.djangoproject.com/en/2.1/ref/models/fields/

3.表与表之间的关联

1.外键

即一对多的关系


school=models.ForeignKey(school,on_delete=models.CASCADE)

在建表时为school添加外键约束,在数据库中的显示为

这里的id是自动创建的,school_id是school添加外键产生的
如果想要与另一张表的其他字段添加外键,需要在加上参数to_filed=’字段名’,同时这个字段必须是unique=True

2.一对一

一对一的创建即在外键创建好后给school_id添加UNIQUE=True的属性

3.多对多

teacher=models.ManyToManyField(teacher)

这样Django会默认添加一张表为

表示多对多的关系。
除了这种方式也可以手动创建一个表,手动添加两个外键来实现多对多。

增删改查的操作会在视图函数中进行,所以要先引入到views.py中


from blog.models import *

1.增加

1.普通字段

create方式


student.objects.create(name="student1",num=1,school=school_obj)
或者
student.objects.create(**{"name":"student1","num"="1","school"=obj"})

save方式

student_obj=student(

name="student1",num=1,school=school_obj

)
student_obk.save()
或者
student_obj=student()
student_obj.name="student1"
student_obj.num=1
student_obj.school=school_obj
2.一对多关系的字段

直接设置外键的id
在student.objects.create中加

school_id=1

通过获取外键对象设置


obj = school.objects.get(name="school1")
student.objects.create(**{"name":"student2","num":2,"school":obj})
3.多对多关系的字段

teacher1=teacher.objects.get(id=1)
teacher2=teacher.objects.get(id=2)
student1=student.objects.get(id=1)
student1.teacher.add(teacher1,teacher2)


teacher1=teacher.objects.filter(id__gt=1,id__lt=10)
student1=student.objects.get(id=1)
student1.teacher.add(*teacher1)


teacher1=teacher.objects.filter(id=1)[0]
student1=student.objects.filter(id__gt=1)
teacher1.student_set.add(*student1)


student1=student.objects.filter(id=1)[0]
student1.teacher.add(2)

如果多对多关系的表是自己手动创建的,那么还可以直接添加该表的字段,利用两个外键的方式添加。

2.删除

1.删除普通表信息

先找到,再删除


student1=student.objects.filter(id=1)[0].delete()

由于django的级联删除,其他表中如student_teacher表中有student1的信息的数据也会删除

2.删除多对多表的信息

student1=student.objects.filter(id=1)[0]
student1.teacher.clear()#删除多对多表中student_id为student1的id的数据
student1.teacher.remove(2)#删除多对多表中teacher_id为2的数据
student1.teacher.remove(*list)#这里也可以为一个列表

反向即使用student_set,其他和正向同样道理

3.修改

1.普通字段的修改

student1=student.objects.get(id=2)
student1.name="sfencs"
student1.save()

``
或者
```python

student1=student.objects.filter(id=2).update(name="sfencs")

update是queryset的方法,可以更新多行数据。
save方法是将一行的所有字段都重新存储一遍,update方法只将要改变的字段存储,效率更高。

2.多对多表的字段的修改

student_obj.teacher.set([1,2,3])# set里是一个列表

先删除,再添加

4.查询

1.查询的有关函数
  • filter(**kwargs)筛选
  • all()所有结果
  • get(**kwargs)得到一个结果,如果结果多于一个或没有都会报错

如果查询结果是一个结果集,即QuerySet对象,那么它还有以下方法

  • values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列
  • exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
  • order_by(*field): 对查询结果排序
  • reverse(): 对查询结果反向排序
  • distinct(): 从返回结果中剔除重复纪录
  • values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
  • count(): 返回数据库中匹配查询(QuerySet)的对象数量。
  • first(): 返回第一条记录
  • last(): 返回最后一条记录
  • exists(): 如果QuerySet包含数据,就返回True,否则返回False。
2.QuerySet对象
  • 查询的结果集就是一个QuerySet对象
  • QuerySet对象就像是一个列表,列表存储着查询出的结果,可以迭代,可以切片
  • Django中QuerySet对象是惰性的,即你得到这个对象的时候并没有真正的在数据库中执行SQL语句,只有用到了QuerySet对象中的数据才会执行SQL语句
  • 想判断QuerySet对象中是否有数据,若写成

if obj:

仍然会执行SQL语句,若使用


if obj.exists():

就可以避免这种问题。

  • QuerySet对象的使用是有cache缓存的,即遍历第二次QuerySet对象的时候数据是从缓存中拿的,不会执行SQL语句
  • 如果QuerySet对象数据量特别大,遍历时为了避免占用大量cache空间,可以将QuerySet对象转换成一个迭代器
3.基础查找

得到对象后,查找字段


student1=student.objects.filter(school_id=1)[0]
print(student1.num)

拿时外键对象的字段


student1 = student.objects.filter(id=2)[0]
print(student1.school.name)

拿多对多关系的字段
因为是多对多关系,得到的会是一个QuerySet对象


student1=student.objects.filter(id=2)[0]
print(student1.teacher.values('name'))
4.使用’__’进行的查找

一对多
school_name为外键对象的字段
school为student表中设置的外键字段


student1=student.objects.filter(id=2).values('school__name')
print(student1)

多对多
和一对多的查询方式一样
teacher为student表中设置的外键字段


student1=student.objects.filter(id=2).values('teacher__name')
print(student1)

反向一对多
student__name中的student为表名


result=school.objects.filter(student__name='student1').values('name')
print(result)

反向多对多
也和反向多对多一样


result=teacher.objects.filter(student__id=2).values('name')
print(result)

其他查询条件

  • id__lt=3 表示id小于3
  • id__gt=1 表示id大于1
  • id__in=[1, 2, 3] 表示id在列表中
  • name__contains=”fenc” 表示name中包含fenc
  • name__icontains=”ven” 表示不区分大小写的包含
  • id__range=[1,3] 表示id在1到3之间,包括1,3
  • name__startswith=’cs’ 表示以cs开头的
  • name__endswith=’cs’ 表示以cs结尾的
  • name__istartswith 不区分大小写
  • name__iendswith 不区分大小写
  • 等等
5.聚合查询aggregate

聚合查询是对QuerySet对象进行计算得到一个结果值作为字典中的值放到一个字典中
这里先引入一些聚合方法


from django.db.models import Avg,Min,Sum,Max

举例:


result=student.objects.all().aggregate(Max('num'))
print(result)

得到的是一个字典:{‘num__max’: 3}
若你想给这个字典的key换一个名字,可以使用:


result=student.objects.all().aggregate(new_name=Max('num'))

输出:{‘new_name’: 3}
也可以同时进行多个聚合查询


result=student.objects.all().aggregate(Avg('num'),Min('num'),new_name=Max('num'))
6.分组查询annotate

分组查询就像是SQL语句中的group by
可以如下使用,即以school_id分组,计算每组的max(num)


result=student.objects.values('school_id').annotate(Max('num'))

也可以对QuerySet对象使用
在查询得出的结果集中进行分组


result=student.objects.filter(school_id__lt=2).values('school_id').annotate(Max('num'))
7.F查询

执行F查询前还得先引入


from django.db.models import F

F查询可以将对象中的值作为变量使用,例如:


result=student.objects.filter(id__gt=F('school_id'))

或者


result=student.objects.update(num=F('school_id')+1)
8.Q查询

惯例先引入


  from django.db.models import Q

Q查询是应用在查询条件上的。
在普通的查询当中,且可以用逗号‘,’表示,可是如果我们想使用或的关系怎么办,使用Q来完成它


student1=student.objects.filter(Q(num=1) | Q(school_id=1))

相当于用Q将条件封装,在Q对象之间使用&或者|或者~
如果想将普通发关键字参数查询与Q查询一起使用,必须将关键字参数查询放到Q的后边

9.扩展查询extra

Django 的查询语法难以简练地表达复杂的 WHERE 子句,于是使用扩展查询extra,其原理相当于给SQL语句中添加子语句
extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
这些参数都是可写可不写的
简单举例:
直接暴力上中文了


student1=student.objects.extra(select={'是否大于2':'num>2'})
print(student1.values('是否大于2')[0]['是否大于2'])

SQL语句其实执行的是SELECT (num>2) AS 是否大于2 FROM `blog_student
可以为select传递参数


student1=student.objects.extra(select=({'是否大于2':'num>%s'}),select_params = ('2',))

可以排序
加‘-’为从大到小,不加为从小到大


student1=student.objects.extra(select=({'是否大于2':'num>%s'}),select_params = ('2',))
student1=student1.extra(order_by=['-是否大于2'])

语句中会添加SELECT (num>’2’) AS 是否大于2 FROM blog_student ORDER BY 是否大于2 DESC
也可以设置where条件,并且给where设置参数


student1=student.objects.extra(select=({'是否大于2':'num>%s'}),select_params = ('2',),where=['id<%s'],params=['4'])

SQL语句为SELECT (num>’2’) AS 是否大于2 FROM blog_student WHERE (id<’4’) ORDER BY 是否大于2 DESC

10.日志查看对应执行的SQL语句

在setting.py中加上下边的代码

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}
LOGGING

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Django之ORM

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Django之ORM

ORM即Object Relational Mapping(对象关系映射)对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言
2023-01-30

Django之模型---ORM简介

ORM,是“对象-关系-映射”的简称,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动。创建项目,在mode
2023-01-30

day 71 Django基础六之ORM

本节目录一 锁二 事务三 xxx四 xxx五 xxx六 xxx七 xxx八 xxx一 锁  行级锁    select_for_update(nowait=False, skip_locked=False) #注意必须用在事务里面,至于如何
2023-01-31

Django-ORM

目录一、ORM介绍二、单表操作表创建新增记录删除记录修改记录三、查询API四、基于双下滑线的模糊查询一、ORM介绍ORM是(对象-关系-映射)的简称:它实现了数据模型与数据库的解耦,对于数据库的操作,就不用去写原生的 SQL 语句,取而代之的是基于面向对象的思
Django-ORM
2019-11-30

Django ORM (四) annot

annotate可以通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值(也可以是平均值或总和),即为查询集的每一项生成聚合。from django.shortcuts import render, HttpResponsefrom
2023-01-31

Django ORM (三) 查询,删除

ORM 查询操作修改 views.py 文件from django.shortcuts import render, HttpResponsefrom app01 import modelsfrom app01.models import
2023-01-31

django--ORM的单表操作

Django--ORM单表操作创建一个新的django项目项目目录结构:Django连接数据库配置重点:第一步:修改settings.py文件DATABASES={default:{ENGINE:django.db.backends.mys
2023-01-30

Django ORM的示例分析

这篇文章给大家分享的是有关Django ORM的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。先来说下两张表emp,dept。emp表的数据如下:dept表的数据如下:然后我们就开始吧,有的同学说我的数据
2023-06-04

Django ORM中,如何使用Coun

示例models解决方法有时候,我们想要获取一个对象关联关系的数量,但是我们不要所有的关联对象,我们只想要符合规则的那些关联对象的数量。示例models# models.pyfrom django.db import modelsclass
2023-01-31

如何了解Django ORM操作

本篇内容主要讲解“如何了解Django ORM操作”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何了解Django ORM操作”吧!查询操作对象.外键字段比如,我们拿到了一个书的信息,我们可以
2023-06-15

Django视图之ORM数据库查询操作API的实例

查询表记录 查询相关API 操作:models.表名.objects.方法()
all(): 查询所有结果 filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 get(**kwargs): 返回与所给
2022-06-05

Django ORM (一) 创建数据库

创建一个 Django 项目及应用django-admin startproject ormcd ormpython manage.py startapp app01在 models.py 上创建数据库结构from django.db im
2023-01-31

django操作非ORM创建的表

django--ORM连接已存在的表问题:django的ORM怎么连接已存在的表,然后进行增删查改操作?工作中会遇见很多二次开发的时候,表都是已经创建好的,用django的ORM进行二次开发,怎么操作数据库中的表呢?下面介绍一种完美解决方案
2023-01-30

Python之元类ORM

什么是元类在Python中一切皆对象,类也是一个对象,实例对象由类创建出来的,类是由元类创建出来的。简而言之,用来创建类的类就叫元类(metaclass)。 函数type其实就是一个元类,type就是Python在背后用来创建所有类的元类。
2023-01-31

django的数据库ORM进阶操作

1、数据库查询的三种方式正向查询:(1)获取全部数据all    v1=models.UserInfo.objects.all().first()    #取出Querryset类型数据,里面是对象,需循环取出    v1.ut    #跨表,ut是外键(2)
django的数据库ORM进阶操作
2017-08-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录