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

前言

创新互联建站专注为客户提供全方位的互联网综合服务,包含不限于网站设计制作、成都做网站、霍林郭勒网络推广、微信小程序定制开发、霍林郭勒网络营销、霍林郭勒企业策划、霍林郭勒品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;创新互联建站为所有大学生创业者提供霍林郭勒建站搭建服务,24小时服务热线:028-86922220,官方网址:www.cdcxhl.com

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

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

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

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

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

表结构设计

还是从实际角度出发。

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

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

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

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

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

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

Django models代码

 
 
 
 
  1. from django.db import models 
  2.  
  3.  
  4. # 作者表 
  5. class 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. # 出版社 
  12. class Publish(models.Model): 
  13.     title = models.CharField(verbose_name="出版社名称", max_length=16) 
  14.     phone = models.CharField(verbose_name="出版联系方式", max_length=11) 
  15.  
  16.  
  17. # 图书 
  18. class 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作者 
  26. class 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图一致!

 
 
 
 
  1. web_author.sql 
  2.  
  3. web_book.sql 
  4.  
  5. web_bookmanyauthor.sql 
  6.  
  7. web_publish.sql 

查询操作

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

前置导入

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

查询所有(all)

语法

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

例如:查询所有作者

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

执行结果

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

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

执行结果

查询指定条件(filter)

语法

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

例如:查询张三的信息

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

执行结果

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

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

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

first

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

代码

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

执行结果

filter支持多条件

假设有俩张三

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

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

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

代码

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

执行结果

常用filter条件列表

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

filter通过__来构造条件

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

get

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

代码

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

执行结果

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

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

示例代码

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

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

query

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

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

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

代码

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

执行结果

总结

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

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

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

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

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

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

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

本文转载自微信公众号「 Python爬虫与数据挖掘」,可以通过以下二维码关注。转载本文请联系 Python爬虫与数据挖掘公众号。

新闻标题:一篇文章带你了解DjangoORM操作(基础篇)
本文URL:http://www.shufengxianlan.com/qtweb/news35/196085.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联