Python Django Views逻辑处理 及 Urls路由规则

一、Views

views模块为MVC中的C——Controller,逻辑处理,是连接MTV中model(数据库数据)与Template(视图模块)的结合,将数据库中的数据显示到视图中

视图的本质就是一个python中的函数

Django中,视图主要用来接受Web请求,并做出响应

视图的响应分为两种:

  1. 以JSON数据形式返回
  2. 以网页的形式返回(重定向到另一个页面、错误视图40X,50X)

视图响应的过程:浏览器输入——>django获取信息并去掉IP:端口号,剩下路径——>urls路由匹配——>视图响应——>回馈到浏览器

Views  视图函数

  • MTV中的View,相当于Controller作用,控制器  接收用户输入(请求),协调模版模型,对数据进行处理
  • 路由器urls
    • urlpatterns
    • 根路由url中,我们会使用include形式将整个子路由添加进来
      • 第一个参数:正则匹配的路径
      • 第二个参数:包含那个路由
      • 第三个参数:namespace
    • 子路由中,前两个参数一致
      • 第三个参数:name
      • 以后我们会根据namespace:name 动态获取我们的路由(path)
    • 请求参数
      • 路径参数
        • 位置参数
          • 使用圆括号包含规则
          • 一个圆括号代表一个参数
          • 代表视图函数上的一个参数
          • 参数个数和视图函数上的参数一一对应(除默认request)
        • 关键字参数
          • 可以在圆括号指定参数名字  (?P<name> reg)
          • 视图函数中存在和圆括号中name对应的参数
          • 参数不区分顺序
          • 个数也需要保持一致,一一对应
      • 请求参数
      • 反向解析
        • 在模版中使用
        • {% url %}
          • {% url 'namespace:name' %}
          • 如果存在位置参数:{% url 'namespace:name' value1 value2 ... %}
          • 如果存在关键字参数:{% url 'namespace:name' key1=value1 key2=value2 ... %}
      • 规则
        • 按照书写顺序,从上到下匹配
        • 没有最优匹配的原则,匹配到就停止
  • 双R
    • Request  
      • django框架根据Http请求报文自动生成的一个对象
      • 包含请求各种信息
      • path、method(GET、POST请求)、encoding、GET(QueryDict、类字典结构key-value,一个key可以对应多个值、get、getlist)、POST、FILES、COOKIES、session、is_ajax()
      • META:元信息  包括:客户端id的所有信息、IP地址等
    • Response

 

二、Urls

路由

  • 按照列表的书写顺序进行匹配,从上到下匹配,没有最优匹配的概念
  • 路由规则编写:通常直接指定'xxx',在结尾添加反斜线  /,path(‘xxx/', views.xxx)

 

URL组成:http |  ://www.xxx.com  |  /xx/index/  |  ?u_token=xxx&u_time=14.37  |  #footer

  • http:schema协议    常见有http、https、ftp传文件、rtmp直播流
  • www.xxx.com:域名  ip:port  http没有书写端口则默认是80端口
  • /xxx/index/:路径path    相当于主机的绝对路径
  • ?u_token=xxx&u_time=14.37:GET请求参数(QueryString 查询参数)
  • #footer:锚点,页面中的定位方式

 

路由规则编写

  • 通常直接指定path("路由路径",  views.xxx)  views中新建方法并逻辑编写
  • 在结尾处直接添加反斜线 \

 

路由路径中参数使用()进行获取

  • 一个圆括号对应视图函数中的一个参数
  • 参数:
    • 路径参数
      • 位置参数:按照书写顺序进行匹配
      • 关键字参数:(?P<参数名称>\d+)  按照参数名称匹配,和顺序无关
    • 参数个数必须和视图函数中参数个数一致(除默认的request以外)
  • 例如:
    from django.urls import path,re_path
    
    urlpatterns = [
        # path('students/', views.students),
        #'^xxx/(?P<id>\d+)/'  路由:/xxx/一位或多位数字
        # re_path('^student/(?P<id>\d+)/', views.student),
    
        re_path('students/$', views.students),
        re_path('students/(\d+)/', views.student),
    
        re_path('time/(\d+)/(\d+)/(\d+)/', views.get_time, name='get_time'),
        re_path('date/(?P<year>\d+)/(?P<month>\d+)/(?P<day>\d+)/', views.get_date,                 name='get_date'),
    ]

     

 

url反向解析

  • 根据根路径中注册的namespace和在子路由中注册name,这两个参数来动态获取我们的路径
  • 在模版中使用 {% url 'namespace:name' %}
  • 如果带有位置参数{% url 'namespace:name' value1 value2 [valuen...] %}
  • 如果带有关键字参数{% url 'namespace:name' key1=value1 key2=value2 [keyn=valuen...] %}
  • 根据路径中注册的标识动态获取路径
  • 反向解析优点:
    • 如果在视图模板中使用硬编码连接,在url配置发生改变时,需要变更的代码会非常多,这样导致我们的代码结构不是很容易维护,使用反向解析可以提高我们代码的扩展性和可维护性。
  • 例如:
    项目urls.py
    from django.contrib import admin
    from django.urls import path, include
    
    path('two/', include(('TwoApp.urls', 'second'), namespace='second')),
    或
    path('two/', include(('TwoApp.urls'), namespace='second')),
    
    
    应用TwoApp urls.py
    from django.urls import path, include
    from TwoApp import views
    
    urlpatterns = [
        path('learn/', views.learn, name='learn'),
    ]
    
    
    .html 中调用
    <a href="{% url 'second:learn' %}">button</a>
    second:项目中定义的命名空间namespace名称,由命名空间名称找到路由two/
    learn:应用中定义的name名称,由name名称找到路由learn/
    
    当更改项目中的path('two/', ...) 为 path('more/', ...)时,路由反向解析为 ip:port/more/learn/
    

    POST反向解析:

  • 项目    urls.py
    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('one/', include(('oneapp.urls', 'first'), namespace='first')),
    ]
    
    
    应用APP  urls.py
    from django.urls import path, include
    from oneapp import views
    
    urlpatterns = [
        path('have/', views.have_request),
        path('create_student/', views.do_create_student, name='do_create_student'),
    ]
    
    
    应用APP    views.py
    def have_request(request):
        return render(request, 'student.html')
    
    def do_create_student(request):
        username = request.POST.get('username')
        return HttpResponse(username)
    
    
    页面    student.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Student</title>
    </head>
    <body>
        <!--表单输入-->
        <form action="{% url 'first:do_create_student' %}" method="post">
            <span>UserName:</span><input type="text" name="username" placeholder="please input username">
            <button>Submit</button>
        </form>
    </body>
    </html>
    
    
    

     

 

Django使用时,2.0版更新后不能使用之前 include namespace 的方式书写

在网页项目中使用include()方法
项目目录中同时存在app/urls.py和proj/urls.py
在proj/urls.py使用include方法
from django.urls import path, include
from app import urls as app_url
urlpatterns = [
    path('xxx/', include(app_url, namespace='common')),
]

在app/urls.py中对应url
from django.urls import path
from.views import index
urlpatterns = [
    path('路由名称', views.方法名, name='index'),
]

runserver发生错误
django.core.exceptions.ImproperlyConfigured: 
Specifying a namespace in include() without providing an app_name is not supported. 
Set the app_name attribute in the included module, 
or pass a 2-tuple containing the list of patterns and app_name instead.
意思为:
在include方法里面指定namespace却不提供app_name是不允许的。
在包含的模块里设置app_name变量,或者在include方法里面提供app_name参数。

解决方法:
在项目的urls.py文件中,即  proj/urls.py中修改

from django.urls import path,include
from app import urls as app_url
urlpatterns = [
    path('xxx/', include((common_url,'common'), namespace='common')),
]

例如:    path('two/', include(('TwoApp.urls', 'second'), namespace='second')),


方法2:在应用  app/urls.py中修改

from django.urls import path
from .views import index
app_name='common'
urlpatterns = [
    path('xxx/',index,name='index'),
]

使用方式:

在页面html5文件中使用反向代理:

<a href="{% url 'second:learn' %}">Go Go Go</a>    #second 为project urls中的namespace    learn为App中的name

 

错误页面定制

  • 在模版中重写对应错误状态码页面,例如新建404.html页面
  • 关闭Debug
  • 实现原则
    • 接近原则
  • 例:在templates中,新建404.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>404</title>
    <head>
    <body>
        <h3>Client Request is Not Found</h3>
    </body>
    </html>

     

 

双R

Request

Django框架会进行自己的包装,之后传递给视图

  • 属性
    • path    请求的完整路径
    • method    请求的方法,常用GET、POST
    • encoding    编码方式,常用utf-8
    • GET    类似字典的参数,包含了get的所有参数
      • 类字典结构
      • 一个key允许对应多个值
      • get、getlist
    • POST    类似字典的参数,包含了post所有参数
    • FILES    类似字典的参数,包含了上传的文件
    • COOKIES    字典,包含了所有COOKIE
    • session    类似字典,表示会话
  • 方法:is_ajax()
    • 判断是否是ajax()
    • 通常用在移动端和JS中
  • META
    • 各种客户端元信息
    • REMOTE_ADDR远端访问IP

Resonse

  • 属性
    • content    返回的内容
    • charset    编码格式
    • status_code    响应状态码(200,3xx,404,5xx)
    • content-type    MIME类型
      • MIME作用:指定传输数据使用哪种形式打开
      • 格式:大类型/小类型    如:image/png    image/jpg
  • Json
    • JsonObject
      • { }
      • key - value
    • JsonArray
      • [ ]
      • 列表中可以是普通数据类型,也可以是JsonObject
    • JsonObject和JsonArray可以嵌套
    • 给移动端的json
    • 给Ajax
      • 前后端
      • DRF
    • Google  Chrome谷歌浏览器
      • jsonFomatter
      • jsonView
  • 方法
    • init    初始化内容
    • write(xxx)    直接写入文本
    • flush()    冲刷缓冲区
    • set_cookie(key, value='xxx',max_age=None,exprise=None)    设置cookie
    • delete_cookie(key)    删除cookie
  • HttpResponse
    • HttpResponseRedirect
      • from django.urls import reverse      def xxx(request): url = reverse('namespace:name')  return HttpResponseRedirect(url)
      • 重定向,暂时 302
      • 简写:redirect
    • JsonResponse
      • 以json格式返回数据
      • 重写了_init_,序列化Json数据,指定content-type为application/json
    • HttpResponsePermanentRedirect
      • 重定向,永久  301
    • HttpResponseBadRequest
      • 400
    • HttpResponseNotFound
      • 404
    • HttpResponseForbidden
      • 403
    • HttpResponseNotAllow
      • 405
    • HttpResponseServerError
      • 500
    • Http404
      • Exception
      • raise  主动抛出异常

 

会话技术

请求后给客户端发送令牌,下次再请求时拿着令牌,服务器就会自动识别客户端

  • 出现场景
    • 服务器如何识别客户端
    • Http在Web开发中基本都是短连接
  • 请求生命周期
    • 从Request开始
    • 到Response结束
  • Cookie
    • 客户端会话技术
      • 数据存储在客户端
    • 键值对存储
    • 支持过期时间  7*24*60*60  7天失效,如果清理缓存,则立马失效
    • 默认Cookie会自动携带本网站所有Cookie
    • Cookie跨域名,跨网站
    • 通过HttpResponse操作客户端
    • 设置Cookie    response.set_cookie(key, value, max_age=None, exprise=None)
      • max_age:整数,指定cookie过期时间
      • expires:整数,指定过期时间,还支持datetime或timedelta,可以指定一个具体日期时间
      • max_age和expries两个选一个指定
      • 过期时间的几个关键时间
        • max_age设置为0, 浏览器关闭失效,设置为None,永不过期
        • expires=timedelta(days=10)    10天后过期
    • Cookie默认不支持中文(添加中文是使用base64加密技术)
    • Cookie    加盐 salt    response.set_signed_cookie(key, value, salt='', **kwargs)
      • 加密
      • 获取时需要解密    request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
    • Cookie    删除    response.delete_cookie('key')
  • Session
    • 服务端会话技术
    • 数据存储在服务器中
    • 默认Session存储在内存中
    • Django中默认会把Session持久化到数据库中
    • Django中Session的默认过期时间是14天
    • 主键是字符串
    • 数据使用数据安全
      • 使用base64加密
      • 在前部添加了混淆
    • Session  设置    request.session['key'] = value
    • Session  获取    request.session.get('key')
    • Session  删除    request.session.flush()    session、cookie一起删除
    • 服务器端会话技术依赖于Cookie
      • django中启用SESSION
      • settings中    INSTALLED_APPS: 'django.contrib.sessions'      MIDDLEWARE:'django.contrib.sessions.middleware.SessionMiddleware'
      • 每个HttpRequest对象都有一个session属性,也是一个类字典对象
  • Token
    • 服务端会话技术
    • 自定义的Session
    • 缺陷:session依赖于cookie    cookie依赖于浏览器
    • 如果使用Web页面开发,使用起来和Session基本一致
    • 如果使用移动端或客户端开发中,通常一Json形式传输,需要移动端自己存储Token,需要获取Token关联数据的时候,主动传递Token
  • Cookie、Session、Token对比
    • Cookie使用更简洁,服务器压力更小,数据不是很安全
    • Session服务器要维护Session,相对安全
    • Token拥有Session的所有优点,自己维护略微麻烦,支持更多的终端

 

CSRF

  • 防跨站攻击
  • 防止恶意注册,确保客户端是我们自己的客户端
  • 使用了cookie中csrftoken进行验证、传输
  • 服务器发送给客户端,客户端将cookie获取过来,还要进行编码转换(数据安全)
  • 如何实现
    • 在我们存在csrf_token标签的页面中,响应会自动设置一个cookie、csrftoken
    • 当我们提交的时候,会自动验证csrfttoken
    • 验证通过,正常执行以后流程,验证不通过,直接403

 

知识点

locals

  • 内置函数
  • 将局部变量使用字典的方式进行打包
  • key是变量名,value是变量中存储的数据

登录

  • 首先有一个页面
    • 页面中有输入框
    • 有登录按钮
  • 点击登录按钮,默认进入个人中心
  • 个人中心可以显示用户名
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值