django---03---函数视图和类视图和路由

一:函数视图:
1:函数视图的定义方式:

1. 函数视图它是一个标准的Python函数。
2. 函数视图中,第一个参数必须定义:第一个参数为请求对象,用于接收用户发送的请求报文。
3. 函数视图中,必须返回响应对象:用于构造响应报文,并响应给用户。
4. 说明:
    请求对象:HttpRequest() 对应的对象
    响应对象:HttpResponse() 对应的对象

定义在;子路由的views.py文件中:

from django.shortcuts import render
from django import http
# Create your views here.

def register (request):
    
    
    return http.HttpResponse("这里假装返回注册页面")

2:创建子路由与注册子路由:
在子路由创建urls.py文件。
注册子路由:创建一个固定列表urlpatterns,里面使用path函数,path函数参数是(正则表达式,函数)


from django.urls import path

# 首先需要导入函数视图的文件
from . import views

# django 能够识别的路由变量
urlpatterns = [
    
    # path函数可以根据  正则表达式找到函数
    path("users/register",views.register)
]

3:注册总路由:在工程总路由,工程同名目录/urls.py中包含子应用的路由数据

# 总路由包含子路由语法
    # path('网络地址前缀/', include('子应用.urls')),
    # 或者
    # path('', include('子应用.urls')),
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path("",include("users.urls")),
]

4:重启django,进行测试:
在这里插入图片描述

二:类视图:
现在的需求是:
用户向地址http://127.0.0.1:8000/users/register/发送GET请求,用来获取注册页面。
用户向地址http://127.0.0.1:8000/users/register/发送POST请求,用来实现注册逻辑。
如果函数视图来实现:

def register(request):
    """
    用户注册函数视图
    :param request: 请求对象,包含了请求报文信息
    :return: 响应对象,用于构造响应报文,并响应给用户
    """
    # 获取请求方法,判断是GET还是POST请求
    if request.method == 'GET':
        # 处理GET请求,返回注册页面
        return HttpResponse('这里假装返回注册页面')
    else:
        # 处理POST请求,实现注册逻辑
        return HttpResponse('这里假装实现注册逻辑')

当遇到视图对应的同一个路径,提供了多种不同HTTP请求方式的支持时,便需要在一个函数中编写不同的业务逻辑,代码可读性与复用性都很差。

类视图的好处:
代码可读性好
类视图相对于函数视图有更高的复用性, 如果其他地方需要用到某个类视图的某个特定逻辑,直接继承该类视图即可。

1:类视图的定义方式:

1. 类视图它是一个标准的Python类。
2. 类视图需要继承自Django提供的父类视图View。
3. 在类视图中,
    3.1 需要定义跟请求方法同名的函数来对应不同请求方式
    3.2 在请求方法同名的函数中,还必须定义一个接收请求的参数(同函数视图)
    3.3 在请求方法同名的函数中,还必须返回一个响应对象(同函数视图)
from django.shortcuts import render
from django import http
from django.views import View

class RegisterView(View):
    def get(self, request):
        
        return http.HttpResponse("这里假装get请求返回注册页面")
    
    def post(self, request):
        return http.HttpResponse("这里假装poost请求返回注册页面")

2:注册子路由:


from django.urls import path

# 首先需要导入函数视图的文件
from . import views

# django 能够识别的路由变量
urlpatterns = [

    # path函数可以根据  正则表达式找到函数
    path("users/register/",views.RegisterView.as_view()),
]

注意:我们都知道path第二个参数必须是函数,但是这里为什么是views.RegisterView.as_view(),他又怎么能够调用到我的视图中的函数的呢?
解析:as_view会返回一个内部函数view ,也就是说实际上我们绑定的是view 函数。view函数是如何调用视图中的函数的呢?view函数会调用dispatch函数,这个函数首先把请求的信息:/users/register转换成小写的,然后跟请求列表[get post push…],进行对比,如果匹配成功了,就调用视图中的同名函数。

3:关闭CSRF中间件:
Django默认开启了CSRF防护,会对非GET请求(POST, PUT, DELETE)进行CSRF防护验证,在测试时可以关闭CSRF防护机制
关闭CSRF防护机制是在settings.py文件中注释掉CSRF中间件。

# 中间件
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 为保证非GET请求(POST, PUT, DELETE)可以正常接收,该中间件需要注释掉
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

4:原理展示:
在这里插入图片描述
三:路由:
目标重点是使用path,了解另外两种方式和path的区别。

1:介绍:
路由可以保证用户发送的请求,能够访问到对应的视图
使用路由匹配请求地址,每匹配成功一个就执行对应的函数视图逻辑
定义路由的方法:path()、re_path()、url()
Django1.x版本:url()
Django
2.x版本:path()、re_path()
说明:
为了在版本迭代中,保留旧版本的路由系统,url()在新版中依然可用。
并新增了一个url()的替代方案re_path(),所以url()几乎跟re_path()一样。

2:三种路由方式定义对比:
path()路由语法中,不需要定义正则表达式严格的开头和结尾,因为已经封装好了
re_path()和url()路由语法中,必须要定义正则表达式严格的开头和结尾

 path("users/register/",views.RegisterView.as_view()),
 re_path(r'^users/login/$', views.LoginView.as_view()),
 url(r'^users/login/$', views.LoginView.as_view()),

3:路由的解析顺序:
Django的总路由和子路由都是定义在urlpatterns列表中的。
Django在接收到一个请求时,从总路由文件中的urlpatterns列表中以由上至下的顺序查找对应路由规则。
如果发现规则在include中包含了,则再进入被包含的urls中的urlpatterns列表由上至下进行查询。

4:路由屏蔽问题:
如果网络地址正则表达式没有写完整,比如,没有写严格的开头和结尾,那么就很容易出现前面的路由屏蔽掉了后面的路由。
该问题只会出现在使用re_path()、url()定义路由时出现。因为 path() 定义路由时,网络地址正则表达式默认就是严格的开头和结尾。

过程:
先在视图中定义两个类SayView 和SayhelloView,分别返回say 和sayhello。
然后定义路由的时候,第一个hello没有严格结尾,会导致只能访问第一个,不能访问第二个,因为对于http://127.0.0.1:8000/sayhello/也符合r’^say’,此时直接交给SayView.as_view()。

re_path(r'^say', views.SayView.as_view()),
re_path(r'^sayhello', views.SayHelloView.as_view()),
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奈何碎银没有几两

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值