django orm机制总结
- 格式:docx
- 大小:25.72 KB
- 文档页数:16
Django之Orm 的各种操作1.⼀般操作***必知必会13条***1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37<1> all(): 查询所有结果<2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象models.Customer.objects.filter(id=1) >>> <QuerySet [<Customer: Costomer1>]> 不存在返回⼀个空的queryset,不会报错models.Customer.objects.filter(**{"id":1,..}) 参数也可传字典形式 ---也可传Q对象,后⾯Q对象介绍有<3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有⼀个,如果符合筛选条件的对象超过⼀个或者没有都会抛出错误。
models.Customer.objects.get(id=1) >>> <Customer: Costomer1><4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 models.Customer.objects.exclude(id=1)<5> values(*field): 返回⼀个ValueQuerySet——⼀个特殊的QuerySet,运⾏后得到的并不是⼀系列model的实例化对象,⽽是⼀个可迭代的字典序列 models.Customer.objects.values("name","telephone_number") >>> <QuerySet [{'name': 'Costomer1', 'telephone_number': '182********'}, {'name':'Costomer2', 'telephone_number': '183********'}]><6> values_list(*field): 它与values()⾮常相似,它返回的是⼀个元组序列,values返回的是⼀个字典序列 models.Customer.objects.values_list("name","telephone_number") >>> <QuerySet [('Costomer1', '182********'), ('Costomer2', '183********')]><7> order_by(*field): 对查询结果排序 models.Customer.objects.all().order_by("id") >>> <QuerySet [<Customer: Costomer1>, <Customer: Costomer2>, <Customer: Costomer3><8> reverse(): 对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调⽤(在model类的Meta中指定ordering或调⽤order_by()⽅法)。
Django ORM 数据库操作详解Django是一个使用Python编写的高级Web应用程序框架,它提供了全面的Web开发工具和功能,包括一个强大的对象关系映射(ORM)模块。
ORM模块使得在Django应用程序中进行数据库操作变得非常简单和方便。
本文将详细介绍Django ORM的各种数据库操作。
1. 连接数据库在开始使用Django ORM进行数据库操作之前,首先需要配置数据库连接。
在settings.py文件中,可以使用DATABASES设置来指定数据库的连接信息,包括数据库引擎、数据库名称、用户名、密码等。
2. 创建数据库表Django ORM提供了一个被称为“模型”的概念,它允许开发者通过定义Python类来描述数据库表的结构。
在这个类中,可以定义表的字段名、字段类型、字段约束等信息。
当模型定义完成后,通过运行makemigrations和migrate命令即可自动生成和创建数据库表。
3. 插入数据使用Django ORM插入数据非常简单,只需要创建一个模型对象,并设置相应字段的值,然后调用save()方法即可将数据保存到数据库中。
例如:```pythonperson = Person(name='John', age=30)```4. 查询数据Django ORM提供了强大且灵活的查询API,可以满足各种查询需求。
最基本的查询方法是使用objects属性,通过调用其方法实现数据的筛选和排序。
例如:```python# 查询所有Person对象persons = Person.objects.all()# 按条件查询Person对象persons = Person.objects.filter(age__gte=18)# 排序查询结果persons = Person.objects.order_by('name')```5. 更新数据要更新数据库中的数据,只需要首先查询出所需的数据对象,修改其字段值,然后调用save()方法进行保存。
django实验报告总结一、引言django是一个基于Python的开源Web应用框架,被广泛应用于快速开发高质量的Web应用程序。
本实验报告总结了我在学习和实践django过程中的体会和收获。
二、django的优点和特点1. 简单易用:django提供了简洁明了的语法和强大的功能,使得开发者能够以最少的代码实现复杂的应用逻辑。
2. 高效快速:django的设计目标是高效快速地构建Web应用程序,它提供了丰富的功能和工具,极大地提高了开发效率。
3. 安全可靠:django提供了多种安全机制,包括防止SQL注入、跨站脚本攻击等,保障了应用程序的安全性。
4. 可扩展性:django采用了松散耦合的模块化设计,使得开发者可以方便地扩展和定制框架的各个组件。
5. 社区活跃:django拥有庞大的开发者社区,提供了丰富的文档和资源,解决问题变得更加容易。
三、实验过程及结果在学习django的过程中,我按照以下步骤进行了实验:1. 安装django:首先,我按照官方文档的指引,成功地安装了django框架,并配置好了开发环境。
2. 创建项目和应用:接着,我使用django-admin命令创建了一个新的项目,并通过python manage.py startapp命令创建了一个新的应用。
3. 编写模型:在应用中,我定义了数据模型,使用django提供的ORM功能,将模型映射到数据库,并执行数据库迁移操作。
4. 编写视图和模板:然后,我编写了视图函数,处理用户的请求,并渲染相应的模板,返回给用户。
在模板中,我使用django的模板语言,实现了动态的页面内容展示。
5. 配置URL路由:为了将用户的请求映射到相应的视图函数,我在项目的urls.py文件中配置了URL路由规则。
6. 运行测试:最后,我使用django提供的测试框架,编写了一些测试用例,对应用进行了全面的测试。
测试结果显示,应用的各个功能均正常运行。
四、实验心得和收获通过这次实验,我对django框架有了更深入的了解,并掌握了一些基本的开发技能。
DjangoORM、⼀对⼀、⼀对多、多对多、详解上篇博客也提到这些知识点,可能⼤家还是不太清楚,这篇博客为⼤家详细讲解ORM中的⼏个知识点1.1⾸先我们先看⼀个⼩案例:#_*_coding:utf-8_*_from django.db import models# Create your models here.class Colors(models.Model):colors=models.CharField(max_length=10) #蓝⾊def __str__(self):return self.colorsclass Ball(models.Model):color=models.OneToOneField("Colors") #与颜⾊表为⼀对⼀,颜⾊表为母表description=models.CharField(max_length=10) #描述def __str__(self):return self.descriptionclass Clothes(models.Model):color=models.ForeignKey("Colors") #与颜⾊表为外键,颜⾊表为母表description=models.CharField(max_length=10) #描述def __str__(self):return self.descriptionclass Child(models.Model):name=models.CharField(max_length=10) #姓名favor=models.ManyToManyField('Colors') #与颜⾊表为多对多先来区分⼀下什么是⼀对⼀、多对多 ⼀对⼀:⼦表从母表中选出⼀条数据⼀⼀对应,母表中选出来⼀条就少⼀条,⼦表不可以再选择母表中已被选择的那条数据 ⼀对多:⼦表从母表中选出⼀条数据⼀⼀对应,但母表的这条数据还可以被其他⼦表数据选择共同点是在admin中添加数据的话,都会出现⼀个select选框,但只能单选,因为不论⼀对⼀还是⼀对多,⾃⼰都是“⼀”多对多总结: ⽐如有多个孩⼦,和多种颜⾊、 每个孩⼦可以喜欢多种颜⾊,⼀种颜⾊可以被多个孩⼦喜欢,对于双向均是可以有多个选择应⽤场景⼀对⼀:⼀般⽤于某张表的补充,⽐如⽤户基本信息是⼀张表,但并⾮每⼀个⽤户都需要有登录的权限,不需要记录⽤户名和密码,此时,合理的做法就是新建⼀张记录登录信息的表,与⽤户信息进⾏⼀对⼀的关联,可以⽅便的从⼦表查询母表信息或反向查询外键:有很多的应⽤场景,⽐如每个员⼯归属于⼀个部门,那么就可以让员⼯表的部门字段与部门表进⾏⼀对多关联,可以查询到⼀个员⼯归属于哪个部门,也可反向查出某⼀部门有哪些员⼯多对多:如很多公司,⼀台服务器可能会有多种⽤途,归属于多个产品线当中,那么服务器与产品线之间就可以做成对多对,多对多在A表添加manytomany字段或者从B表添加,效果⼀致⼀对⼀查:#⼦表查询母表,找到红球对应的颜⾊#写法1:print(models.Ball.objects.get(description="红球").color.colors) #返回红,通过⼦表查询母表,写法:"⼦表对象.母表表名的⼩写.母表字段名" ;通过Ball表查到description为"红球",查找到对应colors#写法2,反向从母表⼊⼿:print(models.Colors.objects.get(ball__description="红球").colors) #返回红,通过⼦表查询母表,但形式上是从母表对象⾃⾝直接获取字段,写法:"母表.objects.get(⼦表名⼩写__⼦表字段="xxx").母表字#母表查询⼦表,找到红⾊对应的球的名字#写法1:print(models.Colors.objects.get(colors="红").ball.description) #返回红球,通过母表查询⼦表,写法:"母表对象.⼦表表名的⼩写.⼦表字段名";找到颜⾊为红⾊的Ball的description#写法2,反向从⼦表⼊⼿:print(models.Ball.objects.get(color__colors="红").description) #返回红球,通过母表查询⼦表,但形式上是从⼦表对象⾃⾝直接获取字段,写法:"⼦表.objects.get(⼀对⼀的⼦表字段__母表字段="xxx").⼦增:#添加⼀种颜⾊⿊,并添加⿊球color_obj=models.Colors.objects.create(colors="⿊") #先在母表中创建颜⾊,并实例化给颜⾊表对象models.Ball.objects.create(color=color_obj,description="⿊球") #更新Ball表,color字段为颜⾊表对象,添加description字段备注:增添数据的3种常⽤⽅式#增添数据的三种写法:#写法1:color_obj=models.Colors.objects.create(colors="⿊")models.Ball.objects.create(color=color_obj,description="⿊球")#写法1补充:color_id=models.Colors.objects.create(colors="⿊").idmodels.Ball.objects.create(color_id=color_id,description="⿊球")#写法2:color_obj=models.Colors.objects.create(colors="⿊")ball_obj=models.Ball(color=color_obj,description="⿊球")ball_obj.save()#写法3(字典导⼊):color_obj=models.Colors.objects.create(colors="⿊")ball_dic={'description':"⿊球"}models.Ball.objects.create(color=color_obj,**ball_dic)改:color_obj=models.Colors.objects.get(colors="⿊") #.get()等同于.filter().first()color_obj.colors="灰"color_obj.save()models.Ball.objects.filter(description="⿊球").update(color=color_obj,description="灰球") #update(),delete()是QuerySet的⽅法备注:修改数据的常见⽅式#更新⼀条数据color_obj=models.Colors.objects.get(colors="⿊")color_obj.colors="灰"color_obj.save()#更新多条数据,把满⾜条件的球的description都变为灰球#写法1:models.Ball.objects.filter(color__colors="红").update(description="灰球")#写法2:up_dic={"description":"灰球"}models.Ball.objects.filter(id__gt=0).update(**up_dic)删:models.Ball.objects.get(description="灰球").delete() #对象和QuerySet都有⽅法delete()models.Colors.objects.filter(colors="灰").delete()models.Colors.objects.all().delete() #清空⼀张表⼀对多(外键)查:#外键表联合查询:#外键⼦表查询母表,与⼀对⼀⼦表查询母表形式⼀致#找到红裤衩所属的颜⾊表中的颜⾊--返回:红#写法1:print(models.Clothes.objects.get(description="⼩虎哥").color.colors) #返回红,通过⼦表查询母表,写法:"⼦表对象.母表表名的⼩写.母表字段名" ;通过Clothes表查到description为"⼩虎哥",查找到对#写法2,反向从母表⼊⼿:print(models.Colors.objects.get(clothes__description="⼩虎哥").colors) #返回红,通过⼦表查询母表,但形式上是从母表对象⾃⾝直接获取字段,写法:"母表.objects.get(⼦表名⼩写__⼦表字段="xxx"). #外键母表查询⼦表,与⼀对⼀形式不同,因为母表为"多",不能像⼀对⼀⼀样通过.get().⼦表.⼦表字段的⽅式获取,但与多对多母表查询⼦表⼀致#找到颜⾊为红的所有服装--返回:[<Clothes: ⼤美⼥>, <Clothes: ⼩虎哥>]#写法1:color_obj=models.Colors.objects.get(colors="红")print(color_obj.clothes_set.all()) #注意:⼦表⼩写_set的写法,它实际上是⼀个QuerySet,可以⽤update,delete,all,filter等⽅法#写法2:print(models.Clothes.objects.filter(color=models.Colors.objects.get(colors="红")))#写法2简便写法(推荐):print(models.Clothes.objects.filter(color__colors="红")) #写法:filter(⼦表外键字段__母表字段='过滤条件')#写法3:color_id=models.Colors.objects.get(colors="红").id #通过母表获取到颜⾊为红的idprint(models.Clothes.objects.filter(color_id=color_id)) #filter得到QuerySet,写法:filter(⼦表外键字段_母表主键=母表主键对象)备注:通过QuerySet的.values()⽅法,将QuerySet转化为ValuesQuerySetprint(models.Clothes.objects.filter(color=models.Colors.objects.get(colors="红")).values('color__colors','description')) #获取⼦表的description字段,和母表的colors字段,获取母表字段写法: ⼦表外键字#简写形式补充:print(models.Clothes.objects.filter(color__colors="红").values('color__colors','description'))#返回:[{'description': u'\u7ea2\u5185\u8863', 'color__colors': u'\u7ea2'}, {'description': u'\u7ea2\u5185\u88e4', 'color__colors': u'\u7ea2'}]#如果不加values(),返回的是[<Clothes: ⼤美⼥>, <Clothes: ⼩虎哥>]这样⼀个QuerySet集合,通过values可以形成⼀个列表,列表中的每⼀个元素是⼀个字典,可以通过list()将ValuesQeurySet转化为列表#另外可通过.values_list()将QuerySet转化为ValuesListQuerySet。
django--orm关系字段(ForeignKey、OneToOneField、Many。
django中的关系字段1、ForeignKey字段,即外键字段,对应⼀对多的情况,列如:⼀本书对应⼀个出版社,⼀个出版社可对应多本书。
2、ManyToManyFiled字段,即多对多字段,对应数据库中⼀个数据相互可以对应多条,列如:⼀本书可以有多个作者,⼀个作者可以有多本书3、OneToOneFiled字段,即⼀对⼀字段,通过⽤来将⼀条数据补常⽤的数据单独存放,例如对于作者来说,姓名、作品等是常被查询的,⽽地址、⽣⽇这些是补常⽤的,就可以将这部分数据通过⼀对⼀字段对应分表存放准备⼯作:from django.db import models# Create your models here.class Publisher(models.Model):id = models.AutoField(primary_key=True)name = models.CharField(max_length=12)addr = models.TextField()date = models.DateField()class Book(models.Model):title = models.CharField(max_length=12)price = models.DecimalField(max_digits=6,decimal_places=2)isbn = models.CharField(max_length=20,unique=True)pulisher = models.ForeignKey(to='Publisher')class Author(models.Model):name = models.CharField(max_length=12)gender=models.SmallIntegerField(choices=((1,'男'),(2,'⼥'),(3,'保密')),default=3)phone=models.CharField(max_length=11,unique=True)email=models.EmailField()book = models.ManyToManyField(to='Book',related_name='authors')info = models.OneToOneField(to='Authorinfo',related_name='infos')class Authorinfo(models.Model):birthday=models.DateTimeField()city=models.CharField(max_length=12)is_marry=models.BooleanField()income = models.BigIntegerField()ForeiKeyField2、运⾏django命令:python manage.py makemigrations 和 python manage.py migrate3、在数据库中添加数据:作者表:作者信息表:查询数据的⽅式:查询数据⽅法主要分为两种⽅式:通过对象查询和通过qureset数据查询,其中每种⽅式还对应正向查询和反向查询,解释:例如在上⾯两个表中,⼀对⼀字段在作者表中那么根据作者表查信息表就是正向查询,反之为反向查询ForeiKeyField正向查询通过对象正向查询例如查询id=1的作者的详细信息:步骤:1、获取id=1的作者对象2、通过⼀对⼀字段获取对象3、调⽤字段属性在django脚本中:import osif __name__ == "__main__":os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day65blog.settings")import djangodjango.setup()from app01 import models#获取id =1 的数据对象obj = models.Author.objects.get(id=1)#通过.⼀对⼀字段名的⽅式获取信息表对象并查看属性print(.country,.city)运⾏结果:英国伦敦通过对象反向查询查询国家=英国城市=伦敦的的作者步骤:1、获取满⾜条件的作者信息表对象2、通过.表名⽅法获取对象(当⼀对⼀字段有related_name参数时,⽤该参数的值替代表名_set)from django.db import models# Create your models here.class Author(models.Model):#姓名字段name = models.CharField(max_length=12)#性别字段,choices参数对应选择1、2、3gender = models.SmallIntegerField(choices=((1,'男'),(2,'⼥'),(3,'保密')),default=3)#⼀对⼀字段,related_name参数为反向查找时的别名。
DjangoORM的魔力构建高效的数据库交互Django是一个功能强大而又高效的Web开发框架,而Django的ORM(对象关系映射)作为其独特的一部分,使得数据库交互变得更加简单和高效。
在本文中,将探讨Django ORM的特点和优势,并介绍如何使用Django ORM构建高效的数据库交互。
一、Django ORM的特点与优势Django ORM是基于Python的一个对象关系映射工具,它将数据库表和Python对象之间建立了一种映射关系,使得开发者可以使用面向对象的方式来进行数据库操作。
Django ORM的特点与优势主要包括以下几点:1. 简化的数据库操作:使用Django ORM可以避免直接编写SQL语句,通过简单的Python代码就可以完成对数据库的增删改查操作。
这极大地简化了开发者的工作,降低了学习和使用的难度。
2. 灵活的查询功能:Django ORM提供了丰富的查询API,可以方便地进行复杂的查询操作。
开发者可以根据需求使用链式调用、字段过滤、多表连接等功能来构建灵活的查询语句,减少重复的代码和逻辑。
3. 内置的数据验证:Django ORM对数据的验证和过滤进行了内置支持,可以确保数据的完整性和有效性。
开发者可以使用内置的表单类和模型验证器来进行数据验证,避免了手动编写大量的验证代码。
4. 自动化的数据库迁移:Django ORM提供了自动化的数据库迁移功能,可以方便地进行数据库结构的变更和升级。
通过简单的命令,开发者可以生成和应用数据库迁移文件,无需手动更新数据库表结构,减少了出错的可能性。
二、Django ORM的使用方法下面将介绍使用Django ORM构建高效数据库交互的几个关键步骤:1. 定义模型类:在Django中,使用模型类来定义数据库表的结构和字段。
开发者需要创建一个继承自`django.db.models.Model`的类,并在类中定义各个字段及其属性,例如字段类型、长度、是否唯一等。
Django之ORM详解(字段与记录的增删改查)⽬录Django ORM简介简介:# 什么是ORM : 其实就是对象关系的映射简单来讲: ORM就是能够让⼀个不会sql语句的⼩⽩也能够通过python⾯向对象的代码⽅式简单快捷的操作数据库不⾜之处: 封装程度太⾼有时候sql语句的效率偏低需要你⾃⼰写SQL语句ORM中的类相当于>>>>>数据库中的表ORM中的对象相当于>>>>>数据库中的记对象的属性相当于>>>>>数据库中记录某个字段对应的值models.py:# ORM需要在应⽤下⾯的models.py⽂件来操作# ⽰例:class User(models.Model): # 相当于创建⼀个表,表名为Userid = models.AutoField(primary_key=True,verbose_name='主键')# 相当于SQL:id int primary_key auto_incrementusername = models.CharField(max_length=32,verbose_name='⽤户名')# 相当于SQL:username varchar(32)"""CharField必须要指定max_length参数不指定会直接报错verbose_name该参数是所有字段都有的就是⽤来对字段的解释"""password = models.IntegerField(verbose_name='密码')# 相当于SQL:password int# 注意:orm只能操作表,所以需提前定义好库注意:# 在完成ORM语句操作后需要执⾏数据库迁移命令************************* 数据库迁移命令 **************************python3 manage.py makemigrations # 将操作记录记录到migrations⽂件夹⾥python3 manage.py migrate # 将操作真正的同步到数据库中******************************************************************# 只要你修改了models.py中跟数据库相关的代码就必须重新执⾏上述的两条命令# app01_user就是利⽤ORM创建的表为什么⾃动加了前缀:因为django项⽬可以有多个应⽤,那么多个应⽤之间可能出现表名冲突的情况,加上前缀就可以完全避免这种情况。
Django框架开发经验总结Django是一个高效、灵活且易于使用的Python Web开发框架。
它提供了许多功能和工具,使开发者能够快速构建可靠的Web应用程序。
在使用Django框架进行开发的过程中,我积累了一些宝贵的经验和教训,希望能与大家分享。
一、项目结构的规划在开始一个Django项目之前,合理规划项目的结构非常重要。
一个良好的项目结构可以提高代码的可读性和可维护性。
一般来说,Django项目的结构包括以下几个重要的部分:1.1 应用程序(Apps)Django的应用程序是项目的组成部分,每个应用程序都有自己的功能和模型。
在设计项目结构时,应该将不同的功能模块划分为独立的应用程序,以便于代码的管理和复用。
1.2 数据库模型(Models)在Django中,数据库模型是通过定义Python类来实现的。
在设计数据库模型时,应该遵循最佳实践,如合理使用外键、索引等,以提高数据库的性能和可扩展性。
1.3 视图函数(Views)视图函数负责处理用户请求,并返回相应的响应。
在编写视图函数时,应该将业务逻辑封装在不同的函数或类中,以提高代码的可读性和可维护性。
1.4 URL配置(URLs)URL配置用于将URL映射到对应的视图函数。
在设计URL配置时,应该遵循RESTful风格,合理使用正则表达式和命名空间,以提高URL的可读性和可维护性。
1.5 模板(Templates)模板用于渲染动态内容,并生成最终的HTML页面。
在编写模板时,应该遵循最佳实践,如合理使用模板标签和过滤器,以提高页面的性能和可维护性。
二、数据库操作的技巧在Django中,数据库操作是非常常见的任务。
为了提高数据库操作的效率和可靠性,我总结了以下几点经验:2.1 使用ORM(Object-Relational Mapping)Django的ORM提供了一种便捷的方式来操作数据库,可以避免直接编写SQL语句。
在使用ORM时,应该熟悉常用的查询方法,如filter、exclude、annotate等,以及事务的使用方法,以提高数据库操作的效率和可靠性。
django之ORM数据库操作⼀、ORM介绍映射关系: 表名 --------------------》类名 字段--------------------》属性 表记录-----------------》类实例化对象ORM的两⼤功能: 操作表: - 创建表 - 修改表 - 删除表 操作数据⾏: - 增删改查ORM利⽤pymysql第三⽅⼯具链接数据库Django没办法帮我们创建数据库,只能我们创建完之后告诉它,让django去链接⼆、创建表之前的准备⼯作⼀、⾃⼰创建数据库⼆、在settings⾥⾯配置mysql数据库链接 sqlite3------改为mysql# 修改django默认的数据库的sqlite3为mysqlDATABASES = {'default': {'ENGINE': 'django.db.backends.mysql', #通过这个去链接mysql'NAME': 'djangotsgl','USER':'root','PASSWORD':'123456','HOST':'localhost','PORT':'3306',}} 这样写上以后django会默认的就去链接数据库,这时你会看到报错了,那么解决的办法就是下⾯的这样三、app01中的--init--⽂件import pymysqlpymysql.install_as_MySQLdb()四、创建数据库表models.pyclass Book(models.Model): #必须要继承的nid = models.AutoField(primary_key=True) #⾃增id(可以不写,默认会有⾃增id)title = models.CharField(max_length=32)publishDdata = models.DateField() #出版⽇期author = models.CharField(max_length=32)price = models.DecimalField(max_digits=5,decimal_places=2) #⼀共5位,保留两位⼩数执⾏命令创建:(需要记住的) python3 manage.py makemigrations 创建脚本python3 manage.py migrate 迁移具体例⼦实现model.pyurls.pyviews.pytemplate /index.html1<!DOCTYPE html>2<html lang="en">3<head>4<meta charset="UTF-8">5<meta http-equiv="X-UA-Compatible" content="IE=edge">6<meta name="viewport" content="width=device-width">7<title>Title</title>8<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">9<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>10<style>11 table{12 margin-top: 50px;13 }14</style>15</head>16<body>17<div class="containers">18<div class="row">19<div class="col-md-9 col-md-offset-2">20<table class="table table-hover">21<thead>22<tr>23<th>编号</th>24<th>书名</th>25<th>出版⽇期</th>26<th>作者</th>27<th>价钱</th>28<th>操作</th>29</tr>30</thead>31<tbody>32 {% for book in book_list %}33<tr>34<td>{{ book.nid }}</td>35<td>{{ book.title }}</td>36<td>{{ book.publishDdata|date:'Y-m-d' }}</td>37<td>{{ book.author }}</td>38<td>{{ book.price }}</td>39<td>40<a href="/del/{{ book.nid }}"><button class="btn btn-danger">删除</button></a> 41<a href="/edit/{{ book.nid }}"><button class="btn btn-success">编辑</button></a> 42<a href="/add/"><button class="btn btn-primary">添加</button></a>43</td>44</tr>45 {% endfor %}46</tbody>47</table>48</div>49</div>50</div>51</body>52</html>图⽚内容具体,五、查看数据库的sql语句(加在settings.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',},}}。
Django中orm的惰性机制那么⾸先要知道什么是ORM专业化的⾓度来说:叫对象关系映射(Object-Relation Mapping)是⼀种为了解决⾯向对象与关系数据库存在的互不匹配的现象的技术。
那具体ORM是什么呢?:(在django中,根据代码中的类⾃动⽣成数据库的表也叫--code first)ORM:ORM在⾯向对象模型与关系模型之间架起桥梁。
通过对象与数据库之间映射的元数据,⾃动透明地把编译语⾳中的对象持久化到关系数据库⾥,对数据库的操作可以转换为对对象的操作ORM 有下⾯这些优点。
数据模型都在⼀个地⽅定义,更容易更新和维护,也利于重⽤代码。
ORM 有现成的⼯具,很多功能都可以⾃动完成,⽐如数据消毒、预处理、事务等等。
它迫使你使⽤ MVC 架构,ORM 就是天然的 Model,最终使代码更清晰。
基于 ORM 的业务代码⽐较简单,代码量少,语义性好,容易理解。
你不必编写性能不佳的 SQL。
但是,ORM 也有很突出的缺点。
ORM 库不是轻量级⼯具,需要花很多精⼒学习和设置。
对于复杂的查询,ORM 要么是⽆法表达,要么是性能不如原⽣的 SQL。
ORM 抽象掉了数据库层,开发者⽆法了解底层的数据库操作,也⽆法定制⼀些特殊的 SQL。
Django惰性机制所谓惰性机制:Publisher.objects.all()或者.filter()等都只是返回了⼀个QuerySet(查询结果集对象),它并不会马上执⾏sql,⽽是当调⽤QuerySet的时候才执⾏。
惰性机制之可迭代1 2 3# objs=models.Book.objects.all() # [obj1,obj2,ob3...]# for obj in objs: # 每⼀obj就是⼀个⾏对象,此时会执⾏sql # print("obj:",obj)惰性机制之可切⽚1 2 3 4# objs=models.Book.objects.all() # [obj1,obj2,ob3...] # print(objs[1])# print(objs[1:4])# print(objs[::-1])惰性机制之Django缓存问题Django有⾃⼰的缓存,如果2次的obj对象⼀致,第⼆次的查值直接从缓存中取值。
目录1.1.1 生成查询1.1.2 创建对象1.1.3 保存修改的对象1.1.4 保存ForeignKey 和ManyToManyField 字段1.1.5 检索对象1.1.6 检索所有的对象1.1.7 过滤检索特定对象1.1.8 链接过滤1.1.9 过滤结果集是唯一1.2.1 结果集是延迟的1.2.2 其他的QuerySet方法1.2.3 限制QuerySets1.2.4 字段查找1.2.5 跨关系查询1.2.6 过滤器可参考模型字段1.2.7 缓存查询集1.2.8 比较对象1.2.9 删除对象1.3.1 一次修改多个对象1.3.2 关系对象1.3.3 One-to-many关系1.3.4 Many-to-many关系1.3.5 One-to-one关系1.1.1 生成查询你创建完数据模型,django会自动提供给你数据库抽象的API,可以创建、获取、修改、删除对象,本篇文档讲解如何使用API。
我们参考下面模型,一个weblog:#博客class Blog(models.Model):name = models.CharField(max_length=100)tagline = models.TextField()def __unicode__(self):return #作者class Author(models.Model):name = models.CharField(max_length=50)email = models.EmailField()def __unicode__(self):return #目录class Entry(models.Model):blog = models.ForeignKey(Blog)headline = models.CharField(max_length=255)body_text = models.TextField()pub_date = models.DateTimeField()authors = models.ManyToManyField(Author)n_comments = models.IntegerField()n_pingbacks = models.IntegerField()rating = models.IntegerField()def __unicode__(self):return self.headline1.1.2 创建对象用python对象描述数据库表的数据,django使用一个直观的系统,一个模型类描述一个数据表,一个类的实例描述表的一条详细记录。
使用模型的save()方法将对象创建到数据库。
只有执行save方法时,django才会执行sql把对象写入数据库。
1.1.3 保存修改的对象保存修改仍然使用save()方法 = 'New name'b5.save()1.1.4 保存ForeignKey 和ManyToManyField 字段cheese_blog = Blog.objects.get(name="Cheddar Talk")entry.blog = cheese_blog #为ManyToManyField 增加记录entry.save()joe = Author.objects.create(name="Joe")entry.authors.add(joe) #为ForeignKey 增加记录1.1.5 检索对象从数据库里检索对象,可以通过模型的Manage来建立QuerySet,一个QuerySet表现为一个数据库中对象的结合,他可以有0个一个或多个过滤条件,在SQL里QuerySet相当于select语句用where或limit过滤。
你通过模型的Manage来获取QuerySet,每个模型至少有一个Manage1.1.6 检索所有的对象检索表中所有数据,最简单的方式是用all().all_entries = Entry.objects.all()1.1.7 过滤检索特定对象检索过滤特定查询结果,有两个方法。
filter(**kwargs) 返回一个新的匹配查询参数后的QuerySet exclude(**kwargs) 返回一个新的不匹配查询参数后的QuerySet Entry.objects.filter(pub_date__year=2006)1.1.8 链接过滤Entry.objects.filter(headline__startswith='What').exclude(pub_date__gte=datetime.now()).filter(pub_date__gte=datetime(2005, 1, 1))1.1.9 过滤结果集是唯一三个QuerySets是分开的,第一个是headline以"What"单词开头的结果集,第二个是第一个的子集,即pub_date不大于现在的,第三个是第一个的子集,pub_date大于现在的1.2.1 结果集是延迟的QuerySets是延迟的,创建QuerySets不会触及到数据库操作,你可以多个过滤合并到一起,直到求值的时候django才会开始查询。
如:q = Entry.objects.filter(headline__startswith="What")q = q.filter(pub_date__lte=datetime.now())q = q.exclude(body_text__icontains="food")print q虽然看起来执行了三个过滤条件,实际上最后执行print q的时候,django才开始查询执行SQL到数据库。
1.2.2 其他的QuerySet方法大多数情况你使用all()、filter()和exclude()1.2.3 限制QuerySets使用python的数组限制语法限定QuerySet,如:取前5个Entry.objects.all()[:5]取第五个到第十个Entry.objects.all()[5:10]一般的,限制QuerySet返回新的QuerySet,不会立即求值查询,除非你使用了"step"参数Entry.objects.all()[:10:2]Entry.objects.order_by('headline')[0]Entry.objects.order_by('headline')[0:1].get()1.2.4 字段查找字段查找是指定SQL语句的WHERE条件从句,通过QuerySet的方法filter(), exclude()和get()指定查询关键字。
基本查询field__lookuptype=value例如:Entry.objects.filter(pub_date__lte='2006-01-01')转换为SQL:SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01';如果你传了无效的参数会抛异常数据库API 支持一些查询类型,下面体验一下:a、exactEntry.objects.get(headline__exact="Man bites dog")等价于SELECT ... WHERE headline = 'Man bites dog';如果查询没有提供双下划线,那么会默认__exact=Blog.objects.get(id__exact=14) # Explicit formBlog.objects.get(id=14) # __exact is impliedb、iexact——忽略大小写Blog.objects.get(name__iexact="beatles blog")blog title会匹配"Beatles Blog", "beatles blog", 甚至"BeAtlES blOG".c、contains——包含查询,区分大小写Entry.objects.get(headline__contains='Lennon')转化为SQLSELECT ... WHERE headline LIKE '%Lennon%';icontains 不区分大小写startswith,endswith,istartswith,iendswith前模糊匹配,后模糊匹配1.2.5 跨关系查询Entry.objects.filter(blog__name__exact='Beatles Blog')这个可以跨越你想要的深度。
反向跨关系查询Blog.objects.filter(entry__headline__contains='Lennon')如果跨越多层关系查询,中间模型没有值,django会作为空对待不会发生异常。
Blog.objects.filter(entry__author__name='Lennon');Blog.objects.filter(entry__author__name__isnull=True);Blog.objects.filter(entry__author__isnull=False,entry__author__name__isnull=True);1.2.6 过滤器可参考模型字段目前给的例子里,我们建立了过滤,比照模型字段值和一个固定的值,但是如果我们想比较同一个模型里的一个指端和另一个字段的值,django提供F()——专门取对象中某列值的操作注:n_pingbacks、n_comments为模型Entry属性django支持加减乘除和模计算Entry.objects.filter(n_pingbacks__lt=F('n_comments') * 2)Entry.objects.filter(rating__lt=F('n_comments') + F('n_pingbacks'))Entry.objects.filter(author__name=F('blog__name'))主键查询捷径Blog.objects.get(id__exact=14) # Explicit formBlog.objects.get(id=14) # __exact is impliedBlog.objects.get(pk=14) # pk implies id__exact不仅限于__exact 查询跨越查询Entry.objects.filter(blog__id__exact=3) # Explicit form Entry.objects.filter(blog__id=3) # __exact is implied Entry.objects.filter(blog__pk=3) # __pk implies __id__exactlike语句转义百分号Entry.objects.filter(headline__contains='%')转义为SELECT ... WHERE headline LIKE '%\%%';1.2.7 缓存查询集每个QuerySet都包含一个缓存,以尽量减少对数据库的访问。