Django晋级学习
Django 带参数的路由
path对象
Django使用path对象来定义路由列表,path有四个参数:
- 模式串:匹配用户请求路径的字符串
- 视图函数:匹配上用户请求路径后调用的视图函数
- kwaergs:可选参数,需要额外传递的参数,是一个字典
- 名称(name):给路由命名,在代码中可以使用name进行方向解析(由name获取用户请求路径)
当path中模式串不能满足你的路由规则,还可以使用re_path对象,re_path对象中模式串是正则表达式,其他三个参数和path对象一致。
path注意
- Django从上往下进行匹配,一旦匹配成功就返回
- 一个视图函数可以有多个模式匹配
- 模式前面不需要加’/‘
- 如果匹配失败,则引起异常,Django会调用错误处理视图函数(关闭DEBUG模式)
path匹配规则
- str 字符串参数可以匹配除/和空字符的其他字符串
- int 匹配0和整整数,视图函数的参数将得到一个整型值
- slug 匹配由数字、字母、和_组成的字符串参数
- path 匹配任何非空字符串,包括/
str写法:path('user/',include("App.urls")),
匹配成功:http://127.0.0.1:8000/user/
匹配失败:http://127.0.0.1:8000/login/
int写法:path('show/<int:age>/',views.show,name="show")
如果匹配字符串写了参数,在views里定义函数就需要参数来接收:
1 | def show(request,age): |
匹配成功:http://127.0.0.1:8000/user/show/90/
匹配失败:http://127.0.0.1:8000/user/show/ac/
slug写法:path('list/<slug:name>/',views.list,name="list"),
views:
1 | def list(request,name): |
只要list/后是大小写字母、数字、下划线、-都可以匹配成功
匹配成功:http://127.0.0.1:8000/user/list/A1_/
匹配失败:http://127.0.0.1:8000/user/list/A1.
path写法:path('path/<path:path>/',views.path,name="path"),
views:
1 | def path(request,path): |
该类型匹配除空格外的所有字符串。
re_path
在re_path中,()部分是正则的组,Django在进行url匹配时,就会自动把匹配成功的内容,作为参数传递给视图函数。
re_path无参数匹配手机号:
1 | #urls路由,无参数 |
re_path有参数匹配手机号:
1 | #urls路由,有参数:tel,使用?P标志参数 |
Django 视图
视图本质上是一个函数(类)。这个函数第一个参数的类型时Httpreuest(Djiango传参);它返回一个HttpResponse实例。为了使一个Python的函数成为一个Django可以识别的视图,它必须满足这两个条件。
视图作用:接收并处理请求,调用模型和模板,响应请求
- 响应模板
- 重定向
- 直接响应字符串
- 响应错误模板
- json数据
HttpRequest
HttpRequest是从web服务器传递过来的请求对象,经过Django框架封装产生的,封装了原始的Http请求。
- 服务器接收到Http请求后,Django框架会自动根据服务器传递的环境变量创建HttpRequest对象
- 视图的第一个参数必须是HttpRequest类型的对象
- 在Django.http模块中定义了HttpPeruest对象的API
- 使用HttpRequest对象的不同属性值,可以获取请求中多种信息
常用类型都可以使用这样的方式获取:
获取COOKIES数据:print(request.COOKIES)
获取POST的username的值:print(request.GET.get('username'))
获取POST的username数组字典:print(request.GET.getlist('username'))
QuertDict=>Dict:print(request.GET.dict())
HttpResponse
每一个视图函数必须返回一个响应对象,HttpResponse对象由程序员创建并返回。
参数 | 说明 |
---|---|
content | 字节字符串 |
charset | 字符编码 |
status_code | Http状态码 |
conten_type | 指定输出的MIME类型 |
不调用模板
1 | def post(request): |
调用模块返回
一般使用render函数返回,render只是HttpResponse的包装,还是会返回一个HttpResponse对象。
参数 | 说明 |
---|---|
request | HttpRequest的request参数 |
template_name | HTTP渲染模板 |
context | 渲染的字典文件,默认为空 |
content_type | MIME类型,用于生成文档 |
status | Http响应码,默认200 |
重定向
使用redirect函数来对网页进行重定向到网站首页。
1 | def red(request): |
反向引用
通过name取得路由表地址,首先在路由表”urls.py”中设置路由命名空间:app_name = "App"
调用的时候使用”命名空间:路由名称”调用,实例:
1 | # urls.py |
有参调用:
1 | # urls.py |
错误视图
Django内置了处理HTTP错误的视图(在django.views.defaults包下),主要错误视图包括:
- 403错误:permission_denied (拒绝访问)
- 404错误:page_not_found (文件不存在)
- 500错误:server_error (服务器内部错误)
如果开启DEBUG模式,出错了Django会调用默认模板,如果DEBUG=False;在模板路径下创建404.html、500.html、403.heml,出错后Django会自动调用该模板。
Django 模板
模板用于快速生成动态页面返回给客户端,模板是一个文本。用于分离文档的表现形式和内容。模板定义了占位符以及各种用于规范文档该如何显示的模块标签。模板通常是用于产生HTML,但是Django的模板也能产生任何基于文本格式的文档。模板包含两部分:
- HTML代码
- 模板代码
模板位置
- 在应用中建立templates目录,优点是不需要注册,缺点是多个应用的时候不能复用页面
- 第二种是放在工程的目录下,优点是如果有多个应用,可以调用相同的页面,需要注册
需要修改项目的配置文件setings.py:
1 | TEMPLATES = [ |
模板渲染
渲染方式:
- loader 先加载模板,再进行渲染,好处是多次渲染是不用重新加载
- render 不用加载模板,自动加载,每次渲染都要重新加载一次模板
loader
1 | def index(request): |
render
1 | def index(request): |
模板语法
Django模板中包括两部分:变量和内置标签。变量会在模板渲染时被其值代替,内置标签负责逻辑控制。
变量
变量在模板中的表示为:{{ 变量名 }},变量名就是 render中 context中的键。变量可以基本类型中的数值、字符串、布尔,也可以是字典、对象、列表等。 django提供了点号来访问复杂数据结构。 - 列表、元组的元素可使用索引引用,不能使用负索引,语法:变量.索引 - 字典:字典变量.key - 对象:对象.属性 对象.方法名(方法不能有参数) 当模板系统在变量名中遇到点时,按照以下顺序尝试进行查找: - 字典类型查找 - 属性查找 - 方法查找 - 列表类型索引 如果模板中引用变量未传值,则会被置为空,不会报错,除非你对其进行了操作。 #### 过滤器 过滤器是在变量显示之前修改它的值得一个方法,过滤器使用管道符。过滤器可以串联调用 > {{ 变量|方法 }} > 内置常见过滤器方法: ![](https://img.xpctf.cn/img/20201015093838.png) - 自定义过滤器 内置过滤器功能有限,如果不能满足需求,可以自己定义过滤器。 - 在应用(app)里创建一个包,templatetags,包名指定的 - 在包里创建一个自定义py文件1 | from django import template |
1 | {% load mytag %} {# 加载自定义过滤器 #} |
- if标签
1 | {% if express1 %} |
if表达式中使⽤以下运算符(优先级从⾼到低):
- < >= <= == !=
- is、is not
- not
- and
- or
不要在表达式中使⽤(),可以使⽤if嵌套实现功能
不⽀持 if 3 < b < 5这种写法
- for
遍历可迭代对象
1
2
3{% for i in y%}
#代码块
{% endfor %}反向迭代(reversed)
1 | {% for value in c [1,2,3,4,5] reversed %} |
- empty 当可迭代对象为空或不存在时执⾏,否则不执⾏
1 | {% for value in c %} |
- 字典迭代
1 | e = {'a1':20,'b1':40} |
变量名称 | 变量说明 |
---|---|
forloop.counter | 获取迭代的索引 从1开始 |
forloop.counter0 | 获取迭代的索引 从0开始 |
forloop.revcounter | 迭代的索引从最⼤递减到1 |
forloop.revcounter0 | 迭代的索引从最⼤递减到0 |
forloop.first | 是否为第⼀次迭代 |
forloop.last | 是否为最后⼀次迭代 |
forloop.parentloop | 获取上层的迭代对象 |
1 | {% for i in c %} |
- ifequal/ifnotequal
⽤于判断两个值相等或不等的
1 | {% ifequal var var %} |
- 注释
- 单⾏注释
1 | {# 注释内容 #} |
- 多⾏注释
1 | {% comment %} |
- 跨站请求伪造 csrf
防⽌⽹站受第三⽅服务器的恶意攻击(确定表单到底是不是本⽹站的表单传递过来 的)。csrf相当于在表达中增加了⼀个隐藏的input框,⽤于向服务器提交⼀个唯⼀ 的随机字符串⽤于服务器验证表单是否是本服务器的表单。
编辑settings.py开启csrf
1 | MIDDLEWARE = [ |
表单调用:
1 | <form action="" method="post"> |
全站禁⽤csrf:
1 | #在settings中设置 |
局部禁⽤csrf:
1 | #在不想检验csrf的视图函数前添加装饰器@csrf_exempt。 |
ajax验证csrf:
1 | Ajax提交数据时候,携带CSRF: |
注意:
csrf的意义在于 给每⼀个表单都设置⼀个唯⼀的csrf的值 并且cookie也存储⼀份 当提交表单过来的时候 判断cookie中的值 和csrf_token中的值 是否都为本⽹站⽣ 成的 如果验证通过则提交 否则 403
- 模板导⼊标签( include)
可以把指定html⽂件代码导⼊到当前⽂件,实现模板代码的复⽤/重⽤。语法格式:
1 | {% include '路径/xxx.html' %} |
- url标签
在模板中url标签可⽤于反向解析
1 | <h2><a href="{% url 'App:index' %}">动态⽣成路由地址不带参的跳转</a> |
Django 模板继承
在整个⽹站中,如何减少共⽤⻚⾯区域(⽐如站点导航)所引起的重复和冗余代 码?Django 解决此类问题的⾸选⽅法是使⽤⼀种优雅的策略—— 模板继承 。 本质上来说,模板继承就是先构造⼀个基础框架模板,⽽后在其⼦模板中对它所包 含站点公⽤部分和定义块进⾏重载。 - {% extends "父模板路径" %} 继承⽗模板 - {% block %} ⼦模板可以重载这部分内容 - {{ block.super }}调⽤⽗模板的代码 使⽤继承的⼀种常⻅⽅式是下⾯的三层法: - 创建base.html模板,在其中定义站点的主要外观感受。这些都是不常修改甚 ⾄从不修改的部分。 - 为每种类型的⻚⾯创建独⽴的模板,例如论坛⻚⾯或者图⽚库。这些模板拓展 相应的区域模板。 - ⾃⼰的⻚⾯继承⾃模板,覆盖⽗模板中指定block 注意事项: - 如果在模板中使⽤ {% extends %} ,必须保证其为模板中的第⼀个模板标记。 否则,模板继承将不起作⽤。 - ⼀般来说,基础模板中的 {% block %} 标签越多越好。 - 如果发觉⾃⼰在多个模板之间有重复代码,你应该考虑将该代码放置到⽗模板 的某个 {% block %} 中。 不在同⼀个模板中定义多个同名的 {% block %} 。 - 多数情况下, {% extends %} 的参数应该是字符,但是如果直到运⾏时⽅能确 定⽗模板名称,这个参数也 可以是个变量。Django 静态资源配置
什么是静态资源:css、js、images 需要从外部导⼊的资源
创建static⽂件夹
在项目根目录下创建个static文件夹,用来存储css、js、images等静态资源。
在settings注册
1 | STATIC_URL = '/static/' |
在模板中使⽤静态资源
1 | {% load static %} #放置到模板开头 |
Django 系列文章
Django基础学习:https://www.xpctf.cn/posts/24c5/
Django晋级学习:https://www.xpctf.cn/posts/2f99/
Django模型学习:https://www.xpctf.cn/posts/d0b4/
Django会话学习:https://www.xpctf.cn/posts/7490/
Django Form学习:正在写