Django-DjangoORM多表关系-Django请求生命周期-Django路由层-路由匹配-路由分组-url 反向解-路由分发-路由分发名称空间-页面静态化-python虚拟化环境-django不同版本url路由配置区别-返回json数据给前端-上传文件-02

表与表之间建关系

以图书管理系统为例

设计表

(粗糙版的思路)写出各个表,再分析关系,建立外键(加一个关联字段)/ 增加第三张关联表

1568686090883

Django ORM实现

一般一个 django项目 创建一个数据库

连接MySQL

两步(mysql连接配置、... pymysql.install_as_MySQLdb())

创模型表

先写一部分字段结构,再补充

app 下的models.py 整个文件拷过来

如何创建多对一 的外键关系?(ForeignKey、外键字段 _id 自动加(自己指定了也还会加一个))

如何创建多对多 的第三张表?(两种方式,直接建模型类、 ManyToManyField)

​ 自动第三张表、不会在表里多出这个字段

如何创建一对一 的外键关系?(OneToOneField、也会自动在外界字段后面加 _id)

to=‘publish’关联字段的 ‘publish’ 和 直接 publish 有位置的关系(后者要求先出现了才能用)

本周作业,图书管理系统(至少书籍表的增删改查

迁移同步到数据库

好像是 migrate 创建的表(自带的那堆表)

django请求生命周期

(要会画这张图)

wsgiref(web服务网关接口) 模块不支持高并发(1000不到),只用于本地测试,上线之后会换成 uwsgi 模块

1568687990761

1568688084425

路由层

url 路由匹配(基于正则、django 1.x特有)

匹配规则

urls 中url() 方法,第一个参数其实是一个正则表达式(匹配规则 和 == 是不一样的)

​ 一旦前面的正则匹配到了内容,就不会再继续往下匹配了,而是直接执行对应的视图函数

1568688488246

带来的问题

正是由于上面的特性,当你的项目特别庞大的时候, url 的先后顺序也是你需要考虑的,极有可能出现 url 错乱的现象

不加斜杆也能匹配的原理(django 二次匹配)

django 在路由匹配的时候,当你在浏览器中没有敲最后的斜杆,django会先拿着你没有敲斜杆的结果去匹配,如果没有匹配上,会让浏览器在末尾加斜杆,再发一次请求,再匹配一次,如果还匹配不上,才会返回 404

如果你想取消该机制,不想做二次匹配,可以在 settings.py 中配置,但还是加上比较好(方便嘛)

... 省略一堆配置
# APPEND_SLASH = False  # 该参数默认是 True
... 省略一堆配置

1568688728017

1568688779895

利用正则限制 url

符合正则的几个 url访问

/dasdadtest/
/test/test/dasda/ae

限制结尾了 $ ,那 get 的 ?参数呢?

限制空 r'^$' --> 首页(127.0.0.1:8080

不存在路径自定义 404 页面 --> r'' 请求不存在的 url 会去执行他的视图函数(一般放在最后) --> 会导致 testaddd/ 没加斜杆的这个问题(像环境变量一样全部一遍,不行再去加斜杠再来一次) ---> 一般 404 页面不是这么做的

url 分组相关

无名分组

视图函数定义哪里需要多写一个位置参数占位

会把分组结果当做位置参数传给视图函数

1568690993020

有名分组

视图函数定义的时候需要多写一个参数(与分组名同名)

1568691014195

无名分组有名分组不能混合使用(但是...)

回顾: 函数定义的参数原则之一 --> 位置参数必须放在关键字参数的前面(所以有名分组要防在无名分组后面)

但是,同一种可以有多个(场景:多个有名分组 或者 多个无名分组

url 反向解析 *****

本质:其实就是给你返回一个别名能够返回对应 url 的地址

应用场景 / 有什么用

根本作用:在改变 url 路由配置的时候,其他引用了这个路由的地方能自动解析,不受影响

对于前端,以不变应万变

html 网页中的链接(页面跳转、数据获取接口(只要是发起请求的,都要有一个地址,可以通过解析来配置这个url 地址,在后端 url 里一改,那些连接就自动解析去更改了))

对于后端,也是以不变应万变(主要针对的是 redirect 重定向页面,直接去匹配 url)

后端的 redirect 函数中放的一般都是 url , 如果需求要变动 url ,那所有要 redirect 这个 url 的地方就都要改过来才行(那如果视图函数太多了,久远了,忘记了,改起来漏了一个,对于上线的项目来说,那都不是小事),我们就可以利用 url 反向解析,在后端利用别名获取到(可能会改动的)url 放到变量里,把这个变量放到 redirect 里即可,这样就不会因为 url 的改动而影响到其他功能了

目前接触的解析小回顾总结

其他可能要解析的也想一下,去查一下,学习一下怎么配置(作为技能点,后期用到了岂不是很棒?)

解析什么 场景 写法
静态资源文件路径动态解析 可以随意改静态资源的 url (....好处再补充) 记不清了,回顾下
{{ load static 。。。?}}
url 路由动态解析 统一修改访问的 url(接口等的) urls 、前后端都需要做响应的处理
好像这两天学的还有一个来着?
不知道有没有其他的,待补充

实际操作

改 a 标签的 url --> 有1000个 咋整

  1. 给当前 url 和 视图函数 起一个别名

    1. 后续通过这个别名动态解析出来
  2. 反向解析

    1. 后端

      1. 后端可以在任意位置、任意视图函数通过 reverse 反向解析出对应的url( 导 三板斧那里,再导一个 reverse)

        reverse(‘kk(刚起的别名name)’)

    2. 前端

      1. {% url 'kkk(刚配的别名name)' %}

1568692053313

反向解析无名分组

可以让视图函数直接拿到 url 中的参数(非 get 方式传参,比request.GET.get(‘参数名’) 的更好用),更加形象的还是看下面的便捷之处

这下面的数字,通常是 数据的id值,这样在 url里就能拿到,不需要在 request.GET.get(‘id’) 了

分组的便捷之处(伪代码)

(以获取商品信息为例,随你举什么形象的例子啦)

  • 在配 url 的时候使用分组

  • 可以给视图函数直接传递形(实?)参,函数可以直接拿到这个分组的值(一般是用户id、商品id(各种id)),可以直接进行数据库的操作(一般是根据 id 查数据),然后 把数据对象通过 render 渲染到 html (模板语法可以使用该数据对象)

  • 在 html 中可以用模版语法,给 a 标签等要跳转页面、请求数据(发请求)的地方使用反向解析(所以后续不需要担心 url 改动让这些链接失效),把 id 等内容放到 url 后面( /shopList/123251(比如这是商品id)),可以方便后续 url 解析到视图函数时可以直接拿到对应的id 进行处理

1568693049140

前端,反向解析后面 随便加个数字

1568692658636

后端反向解析,也是指定数字

  • *args 让函数可以随便接收参数(视图函数

  • 后端利用别名反向解析出 url :reverse(‘kk’, args=(1,))

作业

用反向解析完成用户的编辑和删除(前后端都要用)

有名分组反向解析

url 对应的视图函数可以用关键字参数拿到解析到的值(后续完善时可以下 html 中传参 连接显示的是什么?(/kkk/year=1 还是 /kkk/year:1 ?))

urls.py

1568693409290

同无名分组反向解析一样的用法(无名解析的方式也支持有名分组)

后端

1568693346260

前端

1568693445394

但还是推荐 无名分组的反向解析,就只需要记一套做一套,减少脑容量

反向解析取别名特别强调

在同一个应用(app)下,别名不能重复

小疑惑

为什么有多级url? 这个涉及到路由分发

整个django 控制路由,不同应用下有不同的路由

user/index admin/index 所以后面加肯定是有应用场景的

路由分发 *****

为什么有路由分发

当你的 django 项目特别庞大的时候,路由与视图函数对应关系特别特别多,那么你的总路由 urls.py 代码太过冗长,不易维护

每一个应用(app),都可以有自己的 urls.py, static 文件夹, templates 文件夹

也正是基于上述条件,可实现多人分组开发,等多人开发完成之后,我们(仔细想想有哪些牵扯到的地方,要一块改的哦,我还没经验)需要创建一个空的 django项目,然后将多人开发的app全部注册进来,在总路由实现一个路由分发,而不再做路由匹配(来了之后,我只给你分发到对应的app中)

如何配置路由分发

  1. 导入 include(url后面)

    from django.conf.urls import url, include

  2. 导入对应APP urls 文件中的 urls 并取别名 (as)

  3. 配置分发

2、3 如下图

1568694173719

简便写法(原理 ---> importlib 动态导入模块(可能 django 项目内置了,直接就可以用))

1568702273373

在路由分发中 url 路由配置的注意点

总路由中,一级路由的后面千万不能加 $ --> 正则匹配知识点

当你的应用下的视图函数特别多的时候,你也可以建一个 views 文件夹,然后再根据功能的不同,细分,去做不同的 py 文件 --> 解耦合 的思想,尽可能地拆分(怎么形容的?再好好描述一下)

合并应用

注册app

路由分发

名称空间(了解,避免 url 同别名)

解决同一个django 项目中 不同 app 中的 路由配置 url 起了相同的别名无法通过 别名 正确解析 url

(默认解析到的是最后一个(最后一个 app ? 感觉更像是总路由那里放最后(试试是不是最先?)匹配路由的 app))的问题

多个APP起了相同的别名(协同开发还是可能出现的),这个时候用反向解析,这是并不能自动识别应用前缀

如果想避免这种问题的发生

起别名(为了解决别名冲突)

默认情况下 --> 反向解析会出现解析不出来的情况(默认是最后一个(/app02/index))

指定名称空间

或者 指定名称空间

总路由

1568702674106

后端

1568702643858

前端

1568702999577

避免取冲突的别名

起别名的时候不要冲突即可,一般情况下在起别名的时候通常简易以应用名作为前缀

1568703109906

页面伪静态(seo 优化)

静态网页:数据是写死的,万年不变

博客园文章 url 后缀 .html 看着像纯网页,写死的, 这样的就是伪静态

为什么要做伪静态

伪静态网页的设计是为了增加百度等搜索引擎SEO查询力度

其实所有的搜索引擎本质上都是一个巨大的爬虫程序,把所有的数据爬到了他们的服务器,再展示出来

网站优化相关 通过伪静态确实可以提高你的网站被查询出来的概念,但是再怎么优化已抵不过RMB玩家

如何实现伪静态

直接 用 /index.html 来作为路由匹配规则

eg:url 加 .html --> /index/ --> index.html

python项目虚拟环境的创建与使用

一般情况下,我们会给每一个项目配备该项目所需要的模块,其他的,不需要的模块一概不装

虚拟环境就类似于为每个项目项目量身定做的解释器环境

如何创建虚拟环境

每创建一个虚拟环境,就类似于你又下载了一个全新的python解释器(所以虚拟环境也不要创太多,还是占用硬盘资源的)

创建

图里不是使用,是创建,重截图的时候改过来

1568703907001

虚拟环境

一删了就没了,不安全

1568703969848

1568704041963

自己安装其他环境(模块等) django pymysql ...

使用虚拟环境创建项目

前提是前面创建虚拟环境的时候勾上了允许其他项目使用

1568704198525

django不同版本url路由配置的区别

django1.x 跟 django 2.x 版本区别

  1. urls.py 中路由匹配
  • 1.x用的是 url,第一个参数是正则表达式,正则匹配
  • 2.x用的是 path,且第一个参数不再是正则表达式了,而是精准匹配,写什么匹配什么
    • 当你使用 2.x 不习惯时,还可以用 re_path, 2.x 的 re_path 就是 1.x 中的 url
    • 虽然 2.x 中 path不支持正则表达式,但是它支持五种默认的转换器

1568704611251

2.x path 支持的转换器

默认有五个转换器,感兴趣的自己可以课下去试一下
str,匹配除了路径分隔符(/) 之外的非空字符串,这是默认的形式
int,匹配正整数,包含0。
slug,匹配字母、数字以及横杠、下划线组成的字符串。
uuid,匹配格式化的uuid,如075194d3-6885-417e-a8a8-6c931e272f00 。
path,匹配任何非空字符串,包含了路径分隔符(/)
(不能用? )

1568705078089

小案例

1568704829541

django 2.x path 自定义转换器

1568705092818

视图层

小白必会三板斧(前面有文章中又详细例子,这里就不展开了)

HttpResponse

render

redirect

django 视图函数必须要返回一个HttpResonse 对象 √

看源码发现:render、redirect 返回的也还是一个 HttpResponse 对象,继承了 HttpResponse,所以肯定是 HttpResponse 对象

直接返回 json数据给前端(前后端分离会用到)

数据交互、跨语言 --> 通常用 json 格式

下面两种方式都要注意编码方式(json 默认编码,要指定 ensure_ascii)

前后端分离

前端一个人干(前端把 json 转成自定义对象)

​ JSON.stringify() -- json.dumps

​ JSON.parse() -- json.loads

后端另一个人干 (python 后端用字典)

后端只负责产生接口,前端调用该接口能拿到一个大字典

后端只需要写一个接口文档(url 有几个参数,能拿到什么数据。。。),里面描述字典的详细信息以及参数的传递

返回 json 格式数据给前端(前端拿到的也还是字符串,不过可以利用函数解析成json)

利用 json 模块 + HttpResponse 返回 json 数据

1568707012833

利用 JsonResponse 返回 json 数据(Django自带的,要导一下)

下面的中文会乱码

1568707036234

解决乱码

看源码,找到机会( json_dumps_params )

1568707270772

解决方案

1568707324215

扩展 JsonResponse 支持的数据类型

这里举例返回列表

如果返回的不是字典,只需要修改 safe参数 为 false 即可

1568707548176

上传文件

form表单上传文件需要注意的事项

  1. enctype 需要由默认的 urlencoded 要变成 formdata(这两个模式看下网页上到底什么样的)

  2. method 请求方式改为 post

  3. 新建的项目要用 post 请求 ,要把 settings.py 中的 CSRF 中间件 注释掉

  4. 如果 form 表单上传文件,那么后端需要在 request.FILES.get(‘myfile(input标签的name)’)

    ​ 用 .get 取,也是列表最后一个,拿到的是一个对象

1568708064235

file 对象

有很多属性方法,后续研究下(后期工作中项目里肯定会用到文件上传处理的)

1568708183589

将上传的文件写入后端

.chuncks() 获取可迭代文件对象(推荐 .chuncks() ) 但写不写用起来都是一样的 文件对象本身就可迭代对象(搜一下为什么要用 .chuncks() ? )

1568708367645

request 的其他方法

request.method

request.GET

request.POST

request.FILES

request.path

request.get_full_path

1568708574068

本周作业

图书管理系统

猜你喜欢

转载自www.cnblogs.com/suwanbin/p/11538256.html