Django 路由层(url) + 视图层(views)+ 模板层(模板语法)
url控制器
1、url控制器
urls.py: 请求路径与视图函数的映射关系
(1)简单使用:通过正则分组获取url中的动态参数
使用 path 或 re_path
(2)有名分组:给分组起一个名字,实现关键字的传参,起名,就是正则中的分组 (?P<name>\d{4}),用到了正则就要用re_path,如果用了分组命名,那么在views视图函数中,对应的函数的参数的形参要和分组名保持一致。
re_path(r'articles/(?P<year>\d{4})/(?P<month>\d{2})/', views.year_month) #year_month(request,year=,month=)关键字参数
(3)分发:把每一个app自己的url分发各自的路由文件中,需要在自己的app中新建urls.py,
urlpatterns = [ # 先匹配app01/然后去app01.urls文件中匹配其他的 path(r'app01/',include('app01.urls')) ]
(4)反向解析:不要硬编码url,通过别名解析url, 起别名,提交请求时,应用到url中
a、在 form表单 a标签中的反向解析
<form action="{% url "name" %}" class="le"> <a href="{% url "name" %}"></a>
b、在重定向 redirect 中 使用别名
import django.urls import reverse # 需要引入 reverse return redirect(reverse("name"))
c、含有动态参数时,url中含有分组,某些内容为动态时的反向解析
<a href="{% url "edit" book.nid %}" class="btn btn-warning">编辑</a> # 动态传参的反向解析 book.nid由于在{%%}内,所以不需要添加{{}}
<a href="/books/delete/{{ book.nid }}" class="btn btn-success">删除</a> # 动态传参的非反向解析
2、参考链接:
Django1版本 的路由层(URLconf):https://www.cnblogs.com/yuanchenqi/articles/8876685.html
Django2版本 的路由层(URLconf):https://www.cnblogs.com/yuanchenqi/articles/8931472.html
3、Django1 和 Django2的区别
Django1:使用的是 url() 里面匹配合可以使用正则
Django2:使用的是 path() 默认是添加了 ^ $, re_path() 用到正则匹配的时候需要用re_path()
视图(views)
resquest(请求对象)
# 几种常用的request对象的内容,具体的见详细参考链接
print(request.method) # 请求方式 print(request.path) # 请求路径 print(request.POST) # POST的请求数据 字典格式 print(request.GET) # GET的请求数据 字典格式 print(request.META) # 请求头 print(request.get_full_path()) # 路径+参数 print(request.is_ajax()) #是否为ajax()请求
response(响应对象)
响应对象有三种形式,使用前在 views.py 需要导入:
from django.shortcuts import render,HttpResponse,redirect
1、HttpResponse("字符串") #返回字符串值
2、render(request,"xxx.html",{"var_name":name}) # 返回页面
a、读取文件字符串(只有前两个参数的时候)
b、渲染变量(有三个参数的时候),将数据传入模板,在html中通过模板语法来进行传参,
第三个参数与模板语法中的 {{ var_name }} 中的命名保持一致,才能传参成功
3、redirect("url") #返回重定向
注意:重定向的时候可以使用反向解析,也就是使用别名
以登录验证分析重定向的具体过程:
详细参考链接:https://www.cnblogs.com/yuanchenqi/articles/8876856.html
模型层(模板语法template)
模板语法中的变量
形式:{{ }}
1、深度查询(句点符号)
在 Django 模板中(也就是html文件中)遍历复杂数据结构的关键是句点字符, 语法:
{{ var_name }} #在html文件中使用该语法来进行传参,名字要与返回时,传入到参数保持一致
举例:
#views.py中视图函数返回:
return render(request,"index.html",{"student":student,"dic":dic,"date":date,"person_list":person_list})
return render(request,"index.html",locals()) # 也可以使用locals传参,名称要一一对应,
#模板.html中:
<h4>列表:{{ student.0 }}</h4> # student.0 指的是student对象中第1个值,并非之前的student[0] <h4>列表:{{ student.2 }}</h4> <h4>字典:{{ dic.name }}</h4> <h4>日期:{{ date.year }}</h4> <h4>类对象列表:{{ person_list.0.name }}</h4>
注意:句点符也可以用来引用对象的方法,(无参,有返回值,调用时不加括号)
<h4>字典:{{ dic.name.upper }}</h4> #upper是个方法,模板语法中调用方法只能调用无参数的方法,调用的时候不加括号(),并且方法要有返回值,否则没有意义。
模板语法中的过滤器
语法:{{ obj|filter_name:param}}
其中value为传入的对象,可以自己起名,竖线后的内容为固定的过滤形式
<p>{{ value|default:"没有符合条件的选项" }}</p> <p>{{ value|length}}</p> <p>{{ filesize|filesizeformat}}</p> #文件的大小,比如文件传入的字节为89998887,会转换成Mb,自动转化为合适的格式 <p>{{ article|truncatechars:"20"}}</p> #一篇文章,20个字符以后显示 ... <p>{{ article|truncatewords:"4"}}</p> #一篇文章,4个单词以后显示 ... <p>{{ nowdate|date:"Y-m-d"}}</p> # 转化时间格式 <p>{{ value|slice:"2:-1"}}</p> # 对values内容进行分割,显示分割的内容 <p>{{ link|safe}}</p> # link为标签,比如<a>标签,不过滤就会显示成字符串,过滤后就会将<a>标签在页面上进行渲染
模板语法中的标签
形式:{% %}
for 标签和 if 标签 可以嵌套
{% for foo in book_list%} {% if foo ==’西游记’%} <p>{{forloop.counter}}{{foo}}</p> #{{forloop.counter}}获取的是该foo为第几项,并且从 1 开始 {% endif%} {% endfor%} #结尾处要end
with标签可以起别名,用简单的名字代替复杂的变量
{% with total=business.employees.count %}
{{ total }} employee{{ total|pluralize }}
{% endwith %}
csrf_token
在Django中发送post请求会被阻止,但是在form中添加该标签,该form表单的post请求,并能够发送成功
原因:在form表单中会自动生成一个input标签,
<form action="" methon="post"> {% csrf_token %} <input type="text" name="user" class="user"> </form>
模板语法中的继承
{% extends "base.html" %} #子页面中写在最上方,渲染母版
{% block content%} # 遇到此处渲染子页面中的标签,content为起的名字,随便起,不可以重复
...
{% endblock %}
{{ block.super }} # 替换的地方将母版中的内容也渲染出来
用到了母版,就是多个页面类似,只有局部不同,因此可以设计一个母版,其他的页面继承母版。
在母版中需要替换的地方(标签处)用 {% block content%}.....{% endblock %} 包住,在子页面中,直接更改包住的内容即可。
举例:
#母版中:
#1.
{% block title %} #包住 <title>Title</title> {% endblock %}
#2. <div class="col-md-3"> {% block menu %} #包住要替换的内容 <div class="panel panel-success"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> <p><a href="/index1/">首页</a></p> <p><a href="/order1/">订单</a></p> <p> <a href="/shop1/">商品列表</a></p> </div> </div> {% endblock %} </div>
#子页面中:
{% extends 'base.html' %} {% block title %} <title>百度一下</title> {% endblock %} {% block content %} <ul> {% for shop in shop_list %} <li>{{ shop }}</li> {% endfor %} </ul> {% endblock %}
总结:
{% extends %}
标签,它必须是模版中的第一个标签
在base模版中设置越多的 {% block title %}
标签越好
{% block title %}
中标签title名字不要重复
详细参考链接:https://www.cnblogs.com/yuanchenqi/articles/8876892.html