乐之之

知而行乐,乐而行之,天道酬勤,学无止境。
Django框架基础6

本节重点:

  1、path方法函数定义(path(route, view, kwargs, name))

  2、re_path正则表达式匹配('test/(?P<year>[0-9]{4})/', views.year_test)

  3、shell方法插入数据book=Book(....);book.save()

  4、create方法创建Model实例(Book.object.create(...))

  5、get查询方法(Author.objects.get(....))

  6、get_or_create查询(有就查询False,无就创建True)

  7、原生数据库操作——raw()方法查询

  8、原生数据库操作——游标cursor执行SQL语句

一、Django路由Path方法

1、初始path()方法

  path 函数来进行路由的匹配,可通过以下方式进行导入:

#新的2.x版本导入path,导入简化
from django.urls import path
#原来的1.x版本url方式,conf子包
from django.conf.urls import url

  但是之前的 url 模块并没有废止,只是 Django 强烈建议我们使用新模块 path 进行路由的匹配。

2、path方法函数定义

  path 函数在 Django中的的定义如下所示:

path(route, view, kwargs, name)

  它可以接收 4 个参数,其中前两个是必填参数后两个为可选参数。参数解析如下:

  • route:是一个匹配 URL 的准则(类似正则表达式)。当 Django 响应一个请求时,它会从 urlpatterns 的第一项开始,按顺序依次匹配列表中的项,直到找到匹配的项,然后执行该项映射的视图函数或者 include 函数分发的下级路由,因此,url 路由的编写在 Django中十分的重要!

  • view:指的是处理当前 url 请求的视图函数。当 Django 匹配到某个路由条目时,自动将封装的 HttpRequest 对象作为第一个参数,被“捕获”的参数以关键字参数的形式,传递给该条目指定的视图函数。

  • kwargs:指使用字典关键字传参的形式给关联的目标视图函数传递参数。

  • name:给 URL 起个别名,常用于 url 的反向解析,避免在模板中适应硬编码的方式使用嵌入 url,在后续章节会进行详细讲解。

  当使用 path 方法关联视图函数时与 url 方法相比更为简化,也更容易让初学者理解。

  path 方法引入了类型转化器(converter type)的概念,以此省去了较为复杂的正则表达式匹配路由的方法。

实例说明如下:

#1.x url方法
url(r'^test/(?P<year>[0-9]{4})/$', views.year_test),
#2.x path方法
path('test/<int:year>/', views.year_test),

  int 支持整数类型的转化,在上述的例子中, year_test 函数接收到的 year 参数就变成整数而不是字符串,从而避免在视图中使用 year=int(year)。

  path 函数定义的<int:year>规则会捕获到 URL 中的值,映射给视图中的同名参数 year ,并根据转换器将参数值转换为指定的类型,这里对应 int 大于等于 0 的整数。

之所以使用转化器,有以下两个原因:

  • 第一是可以将捕获到的字符值转换为对应的类型;

  • 第二是对 URL 中传值的一种限制,避免视图处理出错;

  在使用 url 函数时候,我们遇上这样一种情景:即不同的视图函数使用相同的字段作为参数,那么 url 函数也会使用相同正则表达式,只是它们关联的视图函数不同,但是当这个被关联的字段更改的是后,那么可想而知,我们也需要修改所有的正则表达式,重新匹配它,举例如下:

#views.py 视图函数
def year_test(request, year):
    year = int(year) # 转换整形

  urls.py 中配置路由如下所示:

from django.conf.urls import url #引入url方法
urlpatterns = [
    url('test/(?P<year>[0-9]{4})/', year_tst),
    url('test/(?P<id>[a-zA-Z0-9]+)/num/', num_view),
    url('test/(?P<id>[a-zA-Z0-9]+)/num1/', num1_view),
    url('test/(?P<id>[a-zA-Z0-9]+)/num2/', num2_view),
]

  利用 path 方法中提供的类型转换器就很好的解决了这一问题。

3、path方法类型转化器

  Django 默认支持 5 个类型转换器,在大多数情况下,绝对可以满足我们的正常业务需求,如果不能,Django 同样提供了自定义转换器。

  下面介绍 Django 默认支持的转换器,如下所示:

  • str:匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式;

  • int:匹配正整数,包含0;

  • slug:匹配字母、数字以及横杠、下划线组成的字符串;

  • uuid:匹配格式化的 uuid,如 075194d3-6885-417e-a8a8-6c931e272f00;

  • path:匹配任何非空字符串,包含了路径分隔符。

4、re_path正则表达式匹配

  Django 2.x 之后也支持我们使用正则表达式来捕获值,在这里需要使用 re_path(),而不是前面介绍的 path()。我们使用带命名的正则表达式分组,语法如下:

(?P<name>pattern) 

  其中,尖括号里的name为分组名,pattern为正则表达式。re_path()同样包含于django.urls模块中,所以同样使用如下方式进行导入。示例如下:

from django.urls import path, re_path  #导入re_path
from . import views
urlpatterns = [
    re_path('test/(?P<year>[0-9]{4})/', views.year_test),
    re_path('test/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/', views.month_test)]

二、Django实现数据插入

  我们之前利用 Model 模型类创建了 index 应用所需的三张数据表,在本节我们介绍如何实现在 Django 项目中创建 Model 的实例对象,即向数据表中插入数据。

1、save方法创建Model实例

  在 cmd 命令行进入项目 manage.py 目录下,然后使用如下命令进入 Django shell 环境。

python manage.py shell 

  然后创建 Model 实例,使用 save() 方法保存数据,如下所示:

from index.models import Book #导入相关model类
#创建Book实例化对象
book=Book(title="Python",public="清华出版社",price="80.00",retail_price="80.00")
book.save()# 调用save方法进行保存
book=Book(title="Flask",public="图灵出版社",price="30.00",retail_price="30.00")
book.save()# 调用save方法进行保存
book=Book(title="Django",public="北大出版社",price="50.00",retail_price="50.00")
book.save()# 调用save方法进行保存

  最后调用 save 方法进行保存。通过上述代码,我们就在数据库中添加了三条有关书籍的记录。

  创建 Book 实例,其实就是填充有关 Model 实例的各个字段,如果设置了默认值或者有允许为 null 的字段可以不填,最后调用 save() 保存实例(该方法没有返回值)。在 save() 执行以后,Django 会将 book实例化数据保存到数据库中。

  注意,每创建一条数据都需要调用一次 save() 方法。

2、create方法创建Model实例

  除了以上方法外,我们也可以使用管理器对象提供的 create() 方法,使用方法如下所示:

Book.objects.create(title="Java",public="北大出版社",price="30.00",retail_price="30.00")

  然后继续插入如下数据:

Book.objects.create(title="MySQL",public="北大出版社",price="35.00",retail_price="35.00")
Book.objects.create(title="C#",public="北大出版社",price="45.00",retail_price="40.00")
Book.objects.create(title="Redis",public="北大出版社",price="25.00",retail_price="25.00")

  这种创建 Model 实例对象的过程比较简单,create 执行之后就在数据库中插入了一条记录,这也是我们推荐使用的方法。

  最后访问数据库可以看到最新插入的数据记录:

三、Django查询数据库操作详解

  在 web 开发过程中,Django 与后台数据库的交互是必不可少的一项,也是实现业务逻辑所需数据的重要方式,所以 Django 的表查询操作就显的尤为重要。在本节我们将全面阐述 Django 的表查询 API。本节知识属于重中之重,希望各位小伙伴能够尽可能的掌握这些 API,懂得活学活用,熟悉每个 API 的使用场景,这将对后续学习 Django 框架有很大的帮助。

1、返回单条查询结果

(1)使用get查询

  因为 get 查询可能会抛出异常,所以若在项目使用 get 查询的时,经常会与 try..except 异常处理语句一起使用。示例如下:

from index.models import Author
Author.objects.create(name="Tom",email="456789@163.com")
Author.objects.get(name="Tom")

  如果执行两次下面的语句,就会有两个Tom

  Author.objects.create(name="Tom",email="456789@163.com")

  此时执行 Author.objects.get(name="Tom") 会报错

(2)使用get_or_create查询

  该方法的查询过程与 get 类似,都需要传递查询参数,但是不 get 不同的是,它返回值是一个 tuple 对象,通过举例子来说明。

Author.objects.get_or_create(name="Xiaolong")#先查询是否存在若不存在则新建该实例对象

  元组中的第一个元素代表实例对象,第二个元素是布尔值,标识返回的实例对象是否是新创建的,其中 True 代表新建实例对象,False 代表原有实例对象。

2、原生数据库操作方法

  所谓原生数据库操作即使用 SQL 语句来进行数据库的相关的查询操作。

  那你可能会问,Django 已经有 ORM 了,为什么还会提供原生语句的操作呢?

  其实这个问题也很容易想明白,ORM 虽然为我解决了大部分的有业务场景,但是对于复杂的查询来说,ORM 还是有点力不从心,有时无法满足开发者的要求或者书写起来比相较 SQL 语句来说很麻烦,那么在这个时候使用原生 SQL 语解决问题就是不错的选择。

  在 Django 中,可以使用模型管理器(Marager)的 raw 方法来执行 select 语句进行数据的查询。raw 方法的返回值是一个 RawQuerySet 对象,该对象支持索引和切片,同样也可以对它进行迭代得到 Model 实例对象。但是,与 QuerySet 不同的是,它不能执行 fillter、exclude 等方法。下面通过举例说明 raw 方法如何使用。

(1)raw方法语句格式

  使用raw方法的语法格式如下所示:

MyModel.objects.raw('sql语句')

(2)raw方法查询实例

  添加如下代码在index\views.py 中:

def BookName(request):
    books=Book.objects.raw("select * from index_book") #书写sql语句
    return render(request,"index/allbook.html",locals())

  在 templates\index 中创建 allbook.html,代码如下:

{% for book in books %}
<p>{{book.title}}</p>
{% endfor %}

  最后配置路由。

  通过访问 127.0.0.1:8000/index/allbook/,可以得到所有书籍的 title。

(3)游标cursor执行SQL语句

  那么执行非查询语句呢?如何使用原生的 SQL 语句呢? Django 提供了游标 cursor 对数据库进行增删改操作,在 Django 中执行非查询语句必须使用游标进行操作。游标 cursor 定义在 django.db.connection 包中,使用前用下面的方式进行导入:

from django.db import connection

  用创建 cursor 类的构造函数创建 cursor 对象,再使用 cursor 对象执行 SQL 语句。为确保能够在出现异常时释放 cursor 游标,通常使用 with 语句进行创建操,如下所示:

from django.db import connection
with connection.cursor() as cur:
    cur.execute('执行SQL语句')

  使用示例如下:

from django.db import connection
with connection.cursor() as cur:
#调用游标对象的execute方法,更新author的名字
cur.execute('update index_author set name="Jack" where id=3;')
with connection.cursor() as cur: 
# 删除id为3的一条author记录 
cur.execute('delete from index_author where id=3;')

  虽然 Django 提供了 raw SQL的查询方法以及 cursor 游标对象的使用,但是它们很少的被使用,应为这些方法都需要考虑不同数据库的不同特性。Django 官网建议我们尽量使用 ORM 模块来完成相关操作。

 

posted on 2023-04-25 16:23  乐之之  阅读(43)  评论(0编辑  收藏  举报