Django框架day01续
<20210212>
## 1.HTTP协议
1.1 HTTP基本请求与响应
请求 | |
---|---|
POST-新建资源 | 表单提交,上传文件 |
GET-获取资源 | 请求指定资源 |
PUT-修改资源 | 取代指定文档内容 |
DELETE-删除资源 | |
HEAD-获取报头 | 确认服务器响应 |
响应 | |
---|---|
分类 | 分类描述 |
1** | 信息,服务器收到请求,***需要请求者继续***执行操作 |
2** | 成功,操作被成功接收并处理 |
3** | 重定向,01永久重定向,02临时重定向 |
4** | 客户端错误,请求包含语法错误或无法完成请求 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
2.Django处理请求和响应
2.1HttpRequest(请求对象)
View函数的第一个参数为HttpRequest对象,默认填request,视图函数会将request赋值为HttpRequest对象并返回到该视图函数的作用域内使用
HttpRequest的属性
- .path_info: URL字符串
- .method:字符串,表示HTTP请求方法
- .GET:QueryDict查询字典的对象,包含查询字符串的所有数据
- .POST:QueryDict查询字典的对象,包含post表单提交方式的所有数据
- .FILES:类似于字典的对象,包含所有的上传文件信息
- .COOKIES:Python字典,包含所有的cookie,键和值都为字符串
- .session:似于字典的对象,表示当前的会话
- .body: 字符串,请求体的内容(POST或PUT)
- .scheme : 请求协议('http'/'https')
- .get_full_path() : 请求的完整路径(带查询字符串)
- .get_host() : 请求的主机
- .META : 请求中的元数据(消息头)
- .request.META['REMOTE_ADDR'] : 客户端IP地址
2.2HttpResponse(响应对象)
View函数的返回对象,构造函数格式:HttpResponse(content=响应体, content_type=响应体数据类型, status=状态码)
但在后续的返回动态数据,或者返回页面模板,将HttpRequest封装在render()函数中***,所以render的第一个参数填HttpRequest以确定对应的响应***
HttpRequest的参数
- content:表示返回的内容。
- status_code:返回的HTTP响应状态码(默认为200)
- content_type:指定返回数据的的MIME类型(默认为"text/html")。浏览器会根据这个属性,来显示数据。如果是text/html,那么就会解析这个字符串,如果text/plain,那么就会显示一个纯文本。
- 常用的Content-Type如下:
- `'text/html'`(默认的,html文件)
- `'text/plain'`(纯文本)
- `'text/css'`(css文件)
- `'text/javascript'`(js文件)
- `'multipart/form-data'`(文件提交)
- `'application/json'`(json传输)
- `'application/xml'`(xml文件)
> 注: 关键字MIME(Multipurpose Internet Mail Extensions)是指多用途互联网邮件扩展类型。
类型 | 作用 | 状态码 |
---|---|---|
HttpResponseRedirect | 重定向 | 302 |
HttpResponseNotModified | 未修改 | 304 |
HttpResponseBadRequest | 错误请求 | 400 |
HttpResponseNotFound | 没有对应的资源 | 404 |
HttpResponseForbidden | 请求被禁止 | 403 |
HttpResponseServerError | 服务器错误 | 500 |
2.3 处理GET和POST
2.3.1 GET
能够产生GET请求的场景:
- 浏览器地址栏中输入URL,回车后
<a href="地址?参数=值&参数=值">
- form表单中的method为get
GET请求方式中,如果有数据需要传递给服务器,通常会用查询字符串(Query String)传递 【注意:不要传递敏感数据】
-
URL 格式:
xxx?参数名1=值1&参数名2=值2...
- 如:
http://127.0.0.1:8000/page1?a=100&b=200
- 如:
request.GET['参数名'] # QueryDict
request.GET.get('参数名','默认值')
request.GET.getlist('参数名')
# mypage?a=100&b=200&c=300&b=400
# request.GET=QueryDict({'a':['100'], 'b':['200','400'], 'c':['300']})
??????????????????????
# a = request.GET['a']
# b = request.GET['b'] # Error
2.3.2 POST
-
客户端通过表单等POST请求将数据传递给服务器端,如:
#url 可填相对路径 <form method='post' action="/login"> 姓名:<input type="text" name="username"> <input type='submit' value='登陆'> </form>
form 表单的name属性在form表单控件提交数据时,会***自动搜索本表单控件内部的子标签的name属性及相应的值***,再将这些名字和值以键-值对的形式提交***给action指定***的服务器相关位置
在form内能自动搜集到的name属性的标签的控件有
<input name='xxx'>
<select name='yyy'></select>
<textarea name='zzz'></textarea>
服务器端接收参数
if request.method == 'POST':
处理POST请求的数据并响应
else:
处理非POST 请求的响应
#暴力查询
request.POST['参数名'] # request.POST 绑定QueryDict
#询问,无值不报错
request.POST.get('参数名','')
request.POST.getlist('参数名')
取消csrf验证,否则Django将会拒绝客户端发来的POST请求
- 禁止掉 settings.py 中 MIDDLEWARE 中的 CsrfViewsMiddleWare 的中间件(该中间件用于确认用户安全)
Django框架听课笔记day02
3.Templates 模板
模板是可以根据***字典数据动态变化的html网页***,可以根据View视图函数中传递的***字典数据***动态生成相应的HTML网页。
3.1配置模板
-
在(app)主目录下创建templates文件夹
-
在 settings.py 中 TEMPLATES 配置项
-
BACKEND : 指定模板的引擎
-
DIRS : 模板的搜索目录(可以是一个或多个)
'DIRS': [os.path.join(BASE_DIR,'templates'),], TEMPLATES 是一个列表其中嵌套字典,DIR键对应的值是一个列表,该列表内为路径拼接函数,将主目录BASE_DIR和'templates'拼接. 将要使用模板时,Django将由View层向外逐层查找
-
APP_DIRS : 是否要在应用中的
templates
文件夹中搜索模板文件选True将应用自己的templates中的模板,不会再出现默认的小火箭了.
-
OPTIONS : 有关模板的选项
-
3.2 加载模板
通过 loader 获取模板,通过HttpResponse进行响应
from django.template import loader
# 1.通过loader加载模板,此事t已经是数据了
t = loader.get_template("模板文件名.html")
# 2.将t转换成 HTML 字符串,并加入新数据
html = t.render(字典数据)
# 3.用响应对象将转换的字符串 内容返回给浏览器
return HttpResponse(html)
使用 render() 直接加载并响应模板
from django.shortcuts import render
return render(request,'模板文件名.html', 字典数据)
4.模板的传参
模板即是HTML网页,向网页中传入变量,达到渲染,实现功能,接收输入发送输出等.
4.1在模板中使用变量
-
{{ 变量名 }}
-
{{ 变量名.index }}
-
{{ 变量名.key}}
-
{{ 对象.方法 }}
-
{{ 函数名 }}
2.视图函数中***必须将变量封装到字典***中才允许传递到模板上
如果变量过多,可以使用 locals() 将***局部变量全部自动生成字典***
def xxx_view(request)
变量1 = 值1
变量2 = 值2
...
return render(request, 'xxx.html', locals())
4.2模板中的逻辑实现
文档可参见:https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#built-in-tag-reference
将一些服务器端的功能嵌入到模板中
4.2.1 if 标签
#无小括号
{% if 条件表达式1 %}
...
{% elif 条件表达式2 %}
...
{% else %}
...
{% endif %}
-
if 标签里的布尔运算符
- if 条件表达式里可以用的运算符 ==, !=, <, >, <=, >=, in, not in, is, is not, not、and、or
- 在if标记中使用***实际括号是无效的语法***。 如果您需要它们指示优先级,则应使用嵌套的if标记。
4.2.2 for 标签
{% for 变量 in 可迭代对象 %}
... 循环语句
{% empty %}
... 可迭代对象无数据时填充的语句
{% endfor %}
- 内置变量 - forloop
<h2>{{ forloop.counter}}.{{item}}</h2>
将循环次数加到item前面,显示出来
变量 | 描述 |
---|---|
forloop.counter | 循环的当前迭代(从1开始索引) |
forloop.counter0 | 循环的当前迭代(从0开始索引) |
forloop.revcounter | counter值的倒序 |
forloop.revcounter0 | revcounter值的倒序 |
forloop.first | 如果这是第一次通过循环,则为真 |
forloop.last | 如果这是最后一次循环,则为真 |
forloop.parentloop | 当嵌套循环,parentloop 表示外层循环 |
4.2.3 过滤器
-
作用
- 在变量输出时对变量的值进行处理
- 可以通过使用 过滤器来改变变量的输出显示
-
语法
-
{{ 变量 |过滤器1:参数值1 |过滤器2:参数值2 … }}
<参数可以不填>
-
常用的过滤器
过滤器 说明 lower 将字符串转换为全部小写。 upper 将字符串转换为大写形式 safe 默认不对变量内的字符串进行html转义 add: “n” 将value的值增加 n truncatechars:‘n’ (截断)如果字符串字符多于指定的字符数量,那么会被截断。 截断的字符串将以可翻译的省略号序列(“…”)结尾。 注意英文模式中n=‘展示字符数’+’…'
中文模式中n='展示字符数’… -
5.模板的继承
-
模板继承可以使父模板的内容重用,子模板直接继承父模板的全部内容并可以覆盖父模板中相应的块
-
定义***父模板***中的块
block
标签-
block标签:在父模板中定义,可以在子模板中覆盖
{% block block_name %} 定义模板块,此模板块可以被子模板重新定义的同名块覆盖 {% endblock block_name %}
-
-
子模板继承模板
extends
标签- 子模板继承语法标签***(写在子模板文件的第一行)***
{% extends '父模板名称.html' %}
- 子模板 重写父模板中的内容块
{% block block_name %} 子模板块用来覆盖父模板中 block_name 块的内容 {% endblock block_name %}
- 重写的覆盖规则
- 不重写,将按照父模板的效果显示
- 重写,则按照重写效果显示
- 注意
- 模板继承时,服务器端的***动态内容无法继承***
- 子模板继承语法标签***(写在子模板文件的第一行)***
6.url反向解析?
作用***?***:用于同一内容下的页面跳转,如<下一页>操作,***动态获取的url ***
-
url 反向解析是指在view视图或templates模板中,用path定义的名称来查找相应的路由(给路由一个名称)
根据path中的
name=
关键字传参给 url确定了个唯一确定的名字,可以通过这个名字***反向推断出此url信息***path (route, views, ***name=“别名”***)
path('page', views.page_view, name="page_url")
Templates
-
在***模板中*** ->通过***url标签实现地址***的反向解析
{% url '别名' %} {% url '别名' '参数值1' '参数值2' %} ex: {% url 'pagen' '400' %} {% url 'person' age='18' name='gxn' %}
View
-
在***视图函数***中 ->可调用 django中的 reverse方法进行反向解析
from django.urls import reverse reverse('别名', args=[], kwargs={}) ex: print(reverse('pagen',args=[300])) print(reverse('person',kwargs={'name':'xixi','age':18})) #----------------------------------------------------------- path('page/<int:n>',views.page_view,name='page_url') print(reverse('page_url', args=['1000']))#解析出page/1000
同名时找最合适的【参数一致的】;参数一致时,找最后一个;
-
Django框架听课笔记day03
7.静态文件
***不能与服务器端做动态交互的文件***都是静态文件,如:图片,css,js,音频,视频,html文件(部分)
7.1 配置静态文件
1.在根目录下新建文件夹static
2.配置settings.py
#静态的文件访问路由,在地址栏输入的url
STATIC_URL = '/static/'
#静态文件存储路径,服务器文件系统中的目录位置! 元组
STATICFILES_DIRS=(os.path.join(BASE_DIR,'static'),)
3.访问静态文件
-
使用静态文件的访问路径进行访问
访问路径: STATIC_URL = ‘/static/’
<!-- 相对路径--> <img src="/static/images/lena.jpg"> <!-- 绝对路径--> <img src="http://127.0.0.1:8000/static/images/lena.jpg"> <!--外网链接访问,CND内容分发网络--> <img src="外部链接">
-
通过 {% static %}标签访问静态文件
{% static %}
表示的就是静态文件访问路径- 加载 static
{% load static %}
- 使用静态资源时
- 语法:
{% static '静态资源路径' %}
- 示例:
<img src="{% static 'images/lena.jpg' %}">
- 语法:
- 加载 static
*** 3.cnd 分布式内容分发服务器***
img 中的src 填外部的链接
8.Django中的应用APP
应用在Django项目中是一个独立的业务模块,可以包***含自己的路由urls.py,视图view.py,模板templates.py模型models.py***
8.1创建APP
-
用manage.py 中的子命令 startapp 创建应用文件夹,初始化一个新应用
python3 manage.py startapp 应用名称
2.在settings.py里注册应用
INSTALLED_APPS = [
'user', #用户信息模块
'music', #音乐模块
]
8.2 APP的结构
migrations
文件夹 保存数据迁移的中间文件__init__.py
应用子包的初始化文件admin.py
应用的***后台***管理配置文件 <已学>apps.py
应用的属性配置文件models.py
与***数据库***相关的模型映射类文件<重要>tests.py
应用的单元测试文件views.py
定义视图***逻辑处理***函数的文件 <重要>templates
–>app同名子目录
文件夹存放数据渲染文件 .htmlurls.py
应用分布式路由<已学>
8.3 APP分布式路由
主路由配置文件(项目同名子目录/urls.py)可以不处理用户具体路由,主路由配置文件的可以做***请求的分发(分布式请求处理)***。具体的请求可以由各自的应用来进行处理(app目录/urls.py)
1.配置***主路由***
使用include函数
include(‘app命字.url模块名’)
模块
app命字/url模块名.py
文件件里必须有urlpatterns 列表
使用前需要使用from django.conf.urls import include
导入此函数
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
#分布式路由
path('user/',include('user.urls')),
]
#此时以127.0.0.0:8000\user\....为头的地址会转向user这个app中继续查找app中的urls
8.4 APP的templates
应用内部可以配置模板目录
1.应用下手动创建 templates 文件夹
2.settings.py中确认 TEMPLATE 配置项中 的 ‘APP_DIRS’ 值
TEMPLATES = [
'DIRS': [os.path.join(BASE_DIR,'templates'),],
'APP_DIRS': True,]
#此时django会从app中查找模板,但优先从系统下找Templates
3.小问题!
当应用下templates 和 外层系统下templates 都存在时<存在同名的html>,django得***查找模板规则***
- ***优先查找外层***templates目录下的模板
- 按***INSTALLED_APPS配置***下的 应用顺序 逐层查找
app-应用 使用模板的问题
在应用的目录下,在templates建立app同名子目录music,将html模板放到该目录下
views模块即可使用render(request,'music/index.html')
来查找到正确的页面,否则会遵循上文的查找规则找到主目录下的templates
Django框架听课笔记day04
9.Djangomodel模型层
…待续<20210218>