Django 框架结构:

urlspy:路由层
views.py:视图层
templates:模板层
models.py:模型层

路由层

数据处理结果request,是由wsgiref完成

1. 路由匹配

urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^$', views.home),  # 网站首页路由url(r'test/$', views.test),  # 以test/结尾url(r'testadd/$', views.testadd),  # 以testadd/结尾url(r'', views.error)   # 网站不存在页面,该路由存在,网页将不会自动加/重定向
]

url('正则表达式',“视图函数内存地址”)

url(r'^index.html',views.index)

url(r'^index/\d+.html',views.index)
url(r'^index/[0-9]{4}/',views.index)

第一个参数是正则表达式,匹配规则按照从上往下依次匹配,匹配到一个后立即执行对应的函数,不再继续往下匹配

路由过多的时候,可能在它之前就有路由匹配上,目标函数将不会被执行,一可以换前后位置,二换新的路由

PS:路由匹配到的数据默认都是字符串形式

1)分组

无名分组:将加括号的正则表达式匹配到的内容,当做位置参数自动传递给对应的视图函数
有名分组:将加括号的正则表达式匹配到的内容,当做关键字参数自动传递给对应的视图函数

注意:无名分组和有名分组不支持混合使用!!!

但是支持用一类型多个分组匹配

urlpatterns = [url(r'^admin/', admin.site.urls),   url(r'^admin/([0-9]{4})/', admin.site.urls),  # 无名分组,url(r'^test/\d+/', views.test),  # 匹配一个或多个数字,只要有数字访问不受影响url(r'^test/(\d+)/', views.test1),  # 无名分组,会将\d+当做位置参数传递给函数url(r'^test/(\d+)/(\d+)/', views.test11),  # 无名分组多个url(r'^test/(?P<year>\d+)/', views.test2),  # 有名分组,会将\d+当做关键字参数传递给函数url(r'^test/(?P<year>\d+)/(?P<xx>\d+)/', views.test22)  # 有名分组多个
]

def test(request):return HttpResponse('test')def test1(request, xx):print(xx)return HttpResponse('test1')def test11(request, xx, yy):  # 形参可以任意表示,但数量相等print(xx)print(yy)return HttpResponse('test11')def test2(request, year):print(year)return HttpResponse('test2')def test22(request, xx, year):  # 形参必须与路由相同,位置任意print('xx:', xx)print('year:', year)return HttpResponse('test22')

2)反向解析

视图层根据名字动态获取该别名所对应的能够匹配url的路径 from django.shortcuts import reverse

可以给每一个路由与视图函数对应关系起一个别名
这个名字能够唯一标识出对应的路径
注意:这个名字不能重复是唯一的

本质:获取到能够访问名字所对应的视图函数

urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^index/$', views.index, name='index'),  # 路由与视图函数的关系取别名 indexurl(r'^index1/$', views.index1, name='index1'),  # 别名 index1url(r'^test3/(\d+)/', views.test3, name='test3'),  # 别名 test3   url(r'^test4/(\d+)/(\d+)/(\d+)/', views.test4, name='test4'), # 别名 test4]

from django.shortcuts import render,HttpResponse,reversedef index(request):print('url:', reverse('index'))return render(request, 'index.html')def index1(request):print(reverse('test3', args=(1,)))  # test3 需要一个无名分组参数,不传参报错return render(request, 'index1.html')def test3(request, xx):print('xx:', xx)print('url:', reverse('index1'))return HttpResponse('test3')
def test4(request, *args):       print(reverse('test4', args=args)) # /test4/599/288/246/    return HttpResponse(*args) # 599 ??

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body><a href="{% url 'index' %}"></a>
<a href="{% url 'index' %}"></a>
<a href="{% url 'index' %}"></a>
<a href="{% url 'index' %}"></a>
<a href="{% url 'index' %}"></a>
<a href="{% url 'index' %}"></a>
<a href="{% url 'index' %}"></a>
<a href="{% url 'index' %}"></a>
<a href="{% url 'index' %}"></a>
<a href="{% url 'index' %}"></a>
<a href="{% url 'index' %}"></a>
<a href="{% url 'index' %}"></a></body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<a href="{% url 'test3' 10 %}"></a>
<a href="{% url 'test3' 10 %}"></a>
<a href="{% url 'test3' 10 %}"></a>
<a href="{% url 'test3' 10 %}"></a>
<a href="{% url 'test3' 10 %}"></a>
<a href="{% url 'index1' %}"></a>
<a href="{% url 'index1' %}"></a>
<a href="{% url 'index1' %}"></a>
<a href="{% url 'index1' %}"></a></body>
</html>

index1.html

反向解析(根据名字动态获取到对应路径)url(r'^index6668888/$',views.index,name='index')
前端使用{% url '别名' %}
后端使用from django.shortcuts import reversereverse('index')无名分组反向解析url(r'^test/(\d+)/',views.test,name='list')
后端使用reverse('list',args=(10,))
前端使用{% url 'list' user_obj.pk %}有名分组反向解析
后端使用reverse('list',args=(10,))    # 后端有名分组和无名分组都可以用这种形式reverse('list',kwargs={'year':10})    # 下面这个了解即可
前端使用{% url 'list' user_obj.pk %}    # 前端有名分组和无名分组都可以用这种形式{% url 'list' xxx=user_obj.pk %} # 下面这个了解即可  总结:针对有名分组与无名分组的反向解析统一采用一种格式即可 后端 reverse('list',args=(10,)) # 这里的数字通常都是数据的主键值  前端 {% url 'list' user_obj.pk %}

实例

展示数据:
user_list = models.User.objects.all()url(r'^edit/(\d+)', views.edit, name='edit')
前端模板语法{% for user_obj in user_list %}<a href='edit/{{ user_obj.pk }}/'></a>{% endfor %}
增加编辑按钮:
视图函数
from django.shortcuts import reverse
def edit(request, edit_id):url = reverse('edit', args=(edit_id,))
模板{% url 'edit' edit_id %}

3)路由分发

django每一个app下面都可以有自己的urls.py路由层,templates文件夹,static静态文件夹
项目名下urls.py(总路由)不再做路由与视图函数的匹配工作,而是做一个中转

项目名下urls.py:路由分发千万不要$结尾

from django.conf.urls import include
from app01 import urls as app01_urls
from app02 import urls as app02_urls
url(r'^app01/', include(app01_urls)), url(r'^app02/', include(app02_urls)),url(r'^app03/', include('app03.urls'))

在应用下新建urls.py文件,在该文件内写路由与视图函数的对应关系即可

from django.conf.urls import url
from app01 import viewsurlpatterns = [url(r'^index/', views.index)
]

4)名称空间

当多个app中给路由与视图起别名重名的情况,使用名称空间避免反向解析不准的情况

不使用名称空间,可以在起别名的时候加上一些具有唯一标识的前缀

项目urls.py
url(r'^app01/',include(app01_urls,namespace='app01')),
url(r'^app02/',include(app02_urls,namespace='app02'))app01.urls.pyfrom django.conf.urls import urlfrom app01 import viewsurlpatterns = [url(r'^index/',views.index,name='index')]app02.urls.pyfrom django.conf.urls import urlfrom app02 import viewsurlpatterns = [url(r'^index/',views.index,name='index')]app01.views.py
reverse('app01:index')app02.views.py
reverse('app02:index')

5)伪静态网页

搜索优化seo:Search Engine Optimization,利用搜索引擎的规则提高网站在有关搜索引擎内的自然排名

url(r'^index.html',views.index,name='app01_index')
url(r'^index/\d+.html',views.index,name='app01_index')

6)虚拟环境

每一个项目都有属于自己的python环境,避免导入多余的模块造成资源的浪费;

不同的项目配置不同的python解释器,配置需要用到的模块、版本

7)django1.0与django2.0

区别1:django2.0里面的path第一个参数不支持正则,你写什么就匹配,100%精准匹配

区别2:django2.0里面的re_path对应着django1.0里面的url

虽然django2.0里面的path不支持正则表达式,但是它提供五个默认的转换器

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

int,匹配正整数,包含0。

slug,匹配字母、数字以及横杠、下划线组成的字符串。

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

path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)

自定义转换器:

1.正则表达式

2.类 :写两个方法 to_python & to_url

3.注册:起一个名字

url(r'^index/<str:id>',views.index) url(r'^index/<xxx:id>',views.index)

from django.urls import register_converter # 自定义转换器
class FourDigitYearConverter: regex = '[0-9]{4}'def to_python(self, value): return int(value) def to_url(self, value): return '%04d' % value  # 占四位,不够用0填满,超了则就按超了的位数来!
register_converter(FourDigitYearConverter, 'yyyy')

视图层

1. FBV与CBV

后端业务逻辑FBV与CBV完成

FBV:function base views,在视图里使用函数处理请求

CBV:class base views,在视图里使用类处理请求

无论是FBV还是CBV,路由层都是路由对应视图函数内存地址

# CBV 路由层url(r'^login/', views.MyCls.as_view())  # .的左边容器类型# CBV 视图层from django.views import Viewfrom django.shortcuts import HttpResponse, render

class MyCls(View):def get(self, request):return render(request, 'index.html')def post(self, request):return HttpResponse('post')

2. JsonResponse对象

是HttpRespon的子类,第一个参数是一个字典类型,

返回json的字符串,

json_dumps_params参数是一个字典,它将调用json.dumps()方法,'ensure_ascii'值为False时,传入的中文不会被编码为十六进制码

from django.http import JsonResponseimport json

json.dumps(dict, ensure_ascii=False)def index9(request):dic = {'name': 'Tom的哥哥', 'age': 18}return JsonResponse(dic, json_dumps_params={'ensure_ascii': False})输出:
{"name": "Tom的哥哥", "age": 18}

3. 文件上传

前端需注意:

1. method 指定成 post(默认get)

2. enctype 改为 formdata格式(默认urlencoded)

后端注意点:

1. 配置文件settings.py中,注释掉csrfmiddleware中间键

2. 通过request.FILES 获取上传的post文件数据

file_obj = request.FILES.get('my_file')with open(file_obj.name, 'wb') as f:for line in file_obj.chunks():f.write(line)

转载于:https://www.cnblogs.com/zhouyongv5/p/11000990.html

django框架之路由层 视图层......相关推荐

  1. Web框架之Django_03 路由层了解(路有层 无名分组、有名分组、反向解析、路由分发 视图层 JsonResponse,FBV、CBV、文件上传)

    阅读目录 一.路由层:(Django的路由系统) 二.伪静态网页和虚拟环境: 三.FBV与CBV.JsonResponse.文件上传 一.路由层:(Django的路由系统) URL配置(Django项 ...

  2. Django框架的模板层详解

    目录 一.模板简介 二.模板语法之变量 三.模板之过滤器 四.模板之标签 for标签 for ... empty if 标签 with 五.自定义标签和过滤器 六.模板导入和继承 模板导入: 模板继承 ...

  3. Django框架的模型层之多表操作

    目录 一 创建模型 二 表记录的增删改 一对多 多对多 三.基于对象的跨表查询 一对一查询(Author 与 AuthorDetail) 一对多查询(publish与book) 多对多查询 (Auth ...

  4. 分层:数据访问层、业务逻辑层、视图层

    分层:开发模式     数据访问层 业务逻辑层:调用数据访问层 视图层:调用业务逻辑层 数据库表 1.创建项目 2.创建包:     com.zking.util         com.zking. ...

  5. Python Django框架的安装及基本用法

    Django框架   WEB 与 服务器     WEB:表示用户可以浏览的网页内容(HTML.CSS,JS)     服务器:       能够给用户提供服务的机器       硬件 与 软件   ...

  6. yaf 重写index.php,php框架Yaf路由重写

    php框架Yaf路由重写 通常为了友好的URL格式,会进行站点URL的重写,可以在webserver(Nginx)的配置中进行rewrite,也可在在程序端进行 以下使用Yaf框架进行URL的重写,进 ...

  7. Django—路由层,视图层

    路由层urls 浏览器会自动给url后加一个"/" django会自动给路由的正则表达式前面加一个"/" django会给任何不带"/"结尾 ...

  8. Django视图层:URL的反向解析(主路由include之namespace,子路由之name,模板标签{%url%},视图reverse()函数,反向解析示例,URL命名空间

    一.视图层The view layer Django 具有 "视图" 的概念,负责处理用户的请求并返回响应. 二.URL反向解析Reverse resolution of URLs ...

  9. Django视图层:嵌套参数,URLconf在查找什么?指定视图参数的默认值、include()路由转发三种方式、传递额外选项给 include()、传递额外选项给视图

    一.视图层The view layer Django 具有 "视图" 的概念,负责处理用户的请求并返回响应. 二.嵌套参数Nested arguments 正则表达式允许嵌套参数, ...

最新文章

  1. 无人车版「驾校」在长沙开业,7天24小时营业,无人值守的那种
  2. 为Keil添加注释的快捷键
  3. 数据结构大总结系列之B树和R树
  4. Allegro中元器件位号重排并反标回原理图
  5. 顺丰丰桥java demo_顺丰丰桥接口开发-java(前篇)
  6. QT各版本的源码下载地址
  7. orale客户端与数据库连接
  8. vb6编写dll读取dat文件_【STM32Cube_15】使用硬件I2C读取温湿度传感器数据(SHT30)...
  9. gulp+PC前端静态页面项目开发
  10. SpringCloud 基于OAth2.0 搭建认证授权中心_02
  11. 百度之星初赛(A)——T5
  12. 分布式一致性算法2PC和3PC
  13. 理解一下ThreadLocal线程存储---springcloud工作笔记160
  14. 修改android的wifi客户端名称的两种方法
  15. JDK历史版本主要新特性
  16. Python——day12 nonlcoal关键字、装饰器(开放封闭原则、函数被装饰、最终写法)...
  17. Java 操作Word书签(二):添加文本、图片、表格到书签内容
  18. WIN7 安装VS2005
  19. 类似新浪微博中取消关注的弹出确认框
  20. 2018前端走向全栈,Nodejs快速入门视频教程

热门文章

  1. android 8 wifi 不稳定,安卓手机无线网连接不稳定怎么办 wifi连接不稳定的解决方法...
  2. 升级ipython_Pythonipython的安装于升级 - lwgarmstrong
  3. mousewheel 取消_如何暂时取消绑定jquery.mousewheel
  4. Swagger2 简明教程
  5. 推荐一个支持低代码开发的OA开源系统
  6. Correlation Intractability ( CI )
  7. 【BFS】C++羊和狼
  8. 关于Hard Code的思考 - 程序员的管理不能简单使用制度
  9. 在线Markdown 编辑器 作业部落 zybuluo
  10. C++项目新冠疫苗预约系统