一篇文章带你了解Django ORM操作(基础篇)

前言

在日常开发中,需要大量数据库进行增删改查操作

如果头铁的话,使用原生SQL是最好的,毕竟性能又高,又灵活

但是通常情况下,我们不是太需要那么苛刻的性能,也没有那么多刁钻的需求原生SQL

通常会使用简单快捷的ORM进行增删改查

一起看学习一下Django的ORM操作吧

表结构设计

还是从实际角度出发。

假设,现在我需要设计一个简单的图书管理系统,是那种买的书,不是图书馆的书!!!

我想了想,首先,肯定有一个图书表,专门存放图书的信息,最起码是这样的。

但是又想了想,似乎我的书想发布,肯定是需要一个出版社帮我发布的,我肯定不能自己发布所以是这样子的。

又想了想,书肯定是人写的,肯定要有作者,所以还需要一个作者表,应该是这样子的。

又想了想,这一本书如果让一般人编,难度有点大啊,一般都是多人一起完成的,所以大概还有这样一张表。

其实,上述漏点了一个东西,图书需要归属一个出版社的,所以,最终表结构应该是这样的!

Django models代码


1from django.db import models 2 3 4# 作者表 5class Author(models.Model): 6 name = models.CharField(verbose_name="作者姓名", max_length=8) 7 age = models.IntegerField(verbose_name="作者年龄") 8 phone = models.CharField(verbose_name="作者联系方式", max_length=11) 9 10 11# 出版社 12class Publish(models.Model): 13 title = models.CharField(verbose_name="出版社名称", max_length=16) 14 phone = models.CharField(verbose_name="出版联系方式", max_length=11) 15 16 17# 图书 18class Book(models.Model): 19 title = models.CharField(verbose_name="书名", max_length=32) 20 price = models.DecimalField(verbose_name="价格", max_digits=5, decimal_places=2) 21 PublishDate = models.DateField(verbose_name="初版日期") 22 publish = models.ForeignKey(to=Publish, verbose_name="所属出版社", on_delete=models.CASCADE) 23 24 25# 图书Many作者 26class BookManyAuthor(models.Model): 27 book = models.ForeignKey(to=Book, verbose_name="所属图书", on_delete=models.CASCADE) 28 author = models.ForeignKey(to=Author, verbose_name="所属作者", on_delete=models.CASCADE)

Mysql.sql


数据同上述Excel图一致!

web_author.sql

web_book.sql

web_bookmanyauthor.sql

web_publish.sql

查询操作

本次采用单独使用Django ORM的方式,不需要将Django运行起来,所以也不需要写url什么的了!

前置导入

1import os 2import django 3 4# django_orm_demo为我的项目名称 5os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_orm_demo.settings") 6django.setup() 7 8# 导入models一定要在 django.setup() 之后 9from web import models

查询所有(all)

语法

models.<模型类>.objects.all()

例如:查询所有作者

1 2author_list = models.Author.objects.all() 3print(author_list)

执行结果

**例如:**查询所有图书,并且遍历详情

1 2book_list = models.Book.objects.all() 3for book in book_list: 4 print(book.title, book.price, book.PublishDate, book.publish)

执行结果

查询指定条件(filter)

语法

models.<模型类>.objects.filter(<条件>)

例如:查询张三的信息

1 2author = models.Author.objects.filter(name="张三") 3print(author) 4print(author.name)

执行结果

似乎你发现了个错误,'QuerySet' object has no attribute 'name'

这是因为filter(<条件>)查询出来的,可能不止一个值,就像name=张三,可能有很多张三!

所以获取的是一个列表,注意第一个红色圈圈,如果我明明知道就是一个值,也就像取第一个值,咋办?

first

通过first,拿到的就是第一个值,同时也是模型类对象

代码

1author = models.Author.objects.filter(name="张三").first() 2print(author,type(author)) 3print(author.name,author.phone)

执行结果

filter支持多条件

假设有俩张三

如果我想取第二个张三咋办?

要是能写俩条件就好了比如这样name=张三 and age=22

注:filter后面只能跟filter或者first,filter里面的条件都是and查询

代码

1 2# filter里面多个条件是and查询 3author = models.Author.objects.filter(name="张三",age=22).first() 4print(author,type(author)) 5print(author.name,author.phone)

执行结果

常用filter条件列表

熟悉Mysql的可能都知道,有=,<,<=,like等各种范围查询,同样,Django也同样支持!

filter通过__来构造条件

1 2# 包含三 3字段__contains="三" # 原生SQL条件:where 字段 like "%三%" 4# 以三开头 5字段__startswith="三" # 原生SQL条件:where 字段 like "三%" 6# 以三结尾 7字段__startswith="三" # 原生SQL条件:where 字段 like "%三" 8# 为空 9字段__isnull=True # 原生SQL条件:where 字段 IS NULL 10# 不为空 11字段__isnull=False # 原生SQL条件:where 字段 IS NOT NULL 12# in 13字段__in=[1,2,3] # 原生SQL条件:where 字段 IN (1, 2, 3) 14# > 15字段__gt=1 # 原生SQL条件:where 字段 > 1 16# >= 17字段__gte=1 # 原生SQL条件:where 字段 >= 1 18# < 19字段__lt=1 # 原生SQL条件:where 字段 < 1 20# <= 21字段__lte=1 # 原生SQL条件:where 字段 <= 1 22# 日期字段,23日期字段__year=2020 # 原生SQL条件:where 日期字段 BETWEEN 2020-01-01 AND 2020-12-31 24# 日期字段,25日期字段__month=3 # 原生SQL条件:where EXTRACT(MONTH FROM 表名.日期字段) = 3 26# 日期字段,27日期字段__day=4 # 原生SQL条件:where EXTRACT(DAY FROM 表名.日期字段) = 4 28# 时间比大小,|为或的意思 29日期字段__gt|lt|...="2020-10-10" # 原生SQL条件:where 日期字段 > 2020-10-10 30# 比大小还可以是时间类型 31import datetime 32日期字段__gt|lt|...=datetime.date(2020,10,10)# 同上 33# 时间范围筛选 34日期字段__range=("2020-01-01","2020-06-01") # 原生SQL条件:where 时间字段 BETWEEN 2020-01-01 AND 2020-06-01 35日期字段__range=(datetime.date(2020,1,1),datetime.date(2020,6,1)) # 同上

get

其实当我们只需要获取一个值时,还可以使用get

代码

1author = models.Author.objects.get(name="李四") 2print(author,type(author)) 3print(author.name,author.phone)

执行结果

但是这个get不太推荐使用,原因如下

  • 如果get条件获取了俩或俩以上的值,会报错。

  • 如果get条件获取不到值,还是会报错。

示例代码

1author = models.Author.objects.get(name="张三") 2# error:get() returned more than one Author -- it returned 2! 3 4author = models.Author.objects.get(name="不存在") 5# error:Author matching query does not exist. 6author = models.Author.objects.filter(name="不存在").first() 7# 结果:None

所以,推荐使用filter,如果确定只有一条,那就filter().first(),如果需要多条,遍历即可!

query

在某些特殊情况下,我们可能对于查询的结果感到有些意外!

可能需要看看原生SQL是啥,这时候需要用到query

注:query只能用在filter()后面。

代码

1 2sql = models.Author.objects.filter(name="李四").query 3print(sql)

执行结果

总结


本篇通过一个类似实际的需求,进行了一个表结构设计。

书表,出版社表,作者表,图书和作者多对多表

以这几张表为例,进行Django ORM的学习。

学习了如何查询所有,如何条件查询,filter常用条件有哪些

get和filter().first()区别,如何通过query进行查看原生SQL

如果在操作过程中有任何问题,记得下面留言,我们看到会第一时间解决问题。

用微笑告诉别人,今天的我比昨天强,今后也一样。

如果你觉得文章还可以,记得点赞留言支持我们哈。感谢你的阅读,有问题请记得在下方留言噢~

想学习更多关于Python的知识,可以参考学习网址:http://pdcfighting.com/,点击阅读原文,可以直达噢~

-------------------********************************** End **********-------------**-----********-**********************************

往期精彩文章推荐:

欢迎各位大佬点击链接加入群聊【helloworld开发者社区】:https://jq.qq.com/?_wv=1027&k=mBlk6nzX进群交流IT技术热点。

本文转自 https://mp.weixin.qq.com/s/L8Uumq3apFi0nohqvfqINA,如有侵权,请联系删除。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

​一篇文章总结一下Python库中关于时间的常见操作

前言本次来总结一下关于Python时间的相关操作,有一个有趣的问题。如果你的业务用不到时间相关的操作,你的业务基本上会一直用不到。但是如果你的业务一旦用到了时间操作,你就会发现,淦,到处都是时间操作。。。所以思来想去,还是总结一下吧,本次会采用类型注解方式。time包importtime时间戳从1970年1月1日00:00:00标准时区诞生到现在

Python3:sqlalchemy对mysql数据库操作,非sql语句

Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''

Twitter的分布式自增ID算法snowflake (Java版)

概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移