Django视图函数技巧,从入门到实战

简介: Django视图函数技巧,从入门到实战

Django视图函数

Django中一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。

响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。

无论视图本身包含什么逻辑,都要返回响应。大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为views.py的文件中。

视图读取参数

url以查询字符串的方式传参,使用request.GET.get(“name”, default)的形式获取参数值

url以路径传参,使用路径转换器来进行获取参数,在django1.0版本的时候只能通过正则表达式来获取参数。

1.request对象的方法

request.GET:获取url中的查询字符串的数据

request.POST: 获取表单提交的数据

request.path:获取请求的路径

request.method:获取请求的方法得到的值是 请求方法GET or POST等 大写

request.COOKIES:获取请求过来的cookies

request.user:获取请求的用户对象,可以通过它判断用户是否登录,并获取用户信息

request.session:一个既可读又可写的类似字典的对象,表示当前会话

request.META:一个标准的Python字典,包含所有的HTTP首部。具体的头部信息取决于客户端和服务器,

#request.META 字典类型数据,所有的请求头的键都加上了一个HTTP_键名称

print(request.get_full_path()) #当前请求路径包含查询参数

request.encoding

一个字符串,表示提交的数据的编码方式(如果为 None 则表示使用 DEFAULT_CHARSET 的设置,默认为 ‘utf-8’)。

这个属性是可写的,你可以修改它来修改访问表单数据使用的编码。

接下来对属性的任何访问(例如从 GET 或 POST 中读取数据)将使用新的 encoding 值。

如果你知道表单数据的编码不是 DEFAULT_CHARSET ,则使用它。

request.GET 获取查询参数,#不管是post或get请求,当url中含有查询参数时,要在后台的request对象中获取查询参数

,用的属性都是request.GET

浏览器输入查询参数 a=1&b=“景浩”

获取的字典,值是列表类型

print(request) 获取的是WSGIRequest对象

2.视图函数的常用的返回对象

HttpResponse对象,可以直接返回一些字符串

render: 将数据在模板中渲染并显示,使用方式为return render(request, template_path, {k:v})字典中key与value就是要向前端渲染出的数据。

JsonResponse返回一个json类型,通常用于与前端进行ajax交互

(1)response对象

属性

HttpResponse.content:响应内容

HttpResponse.charset:响应内容的编码

HttpResponse.status_code:响应的状态码

(2)JsonResponse对象

JsonResponse是HttpResponse的子类,专门用来生成JSON编码的响应。

 class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None,**kwargs)

这个类是HttpRespon的子类,它主要和父类的区别在于:

1.它的默认Content-Type 被设置为: application/json

2.第一个参数,data应该是一个字典类型,当 safe 这个参数被设置为:False ,那data可以填入任何能被转换为JSON格式的对象,比如list, tuple, set。 默认的safe 参数是 True. 如果你传入的data数据类型不是字典类型,那么它就会抛出 TypeError的异常。

3.json_dumps_params参数是一个字典,它将调用json.dumps()方法并将字典中的参数传入给该方法。

使用HttpResponse对象来响应数据的时候,还可以通过content_type指定格式:

return HttpResponse(json.dumps(data),content_type=“application/json”)

默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。

response = JsonResponse([1, 2, 3], safe=False)

(3)redirect() :给浏览器了一个30x的状态码

参数可以是:

1. 一个模型:将调用模型的get_absolute_url() 函数

2.一个视图,可以带有参数:将使用urlresolvers.reverse 来反向解析名称

3.一个绝对的或相对的URL,将原封不动的作为重定向的位置。

默认返回一个临时的重定向;传递permanent=True 可以返回一个永久的重定向。

示例:

你可以用多种方式使用redirect() 函数。

传递一个具体的ORM对象(了解即可)

将调用具体ORM对象的get_absolute_url() 方法来获取重定向的URL:

301 redirect: 301 代表永久性重定向 网址永久地迁移了,原网址下的资源都没有了

302 redirect: 302 代表临时重定向 临时的做个跳转,项目可能在升级,原网址资源还在

重定向案例

首先在url里面新添加一个用来重定向的路径

建个新页面

视图函数里面,添加跳转视图函数new(),并在login2路径下,用户输入用户名jinghao 即重定向到 /new/ 新页面

redirect里面写的第一个参数为路径,可以添加第二个参数permanent=True,表示永久重定向。默认是临时重定向

浏览器访问,输入用户名jinghao,实现跳转

永久重定向

3.设置响应头和状态码

理论上,客户端发来请求,服务端应根据响应的成功与否,发送给客户端相关的状态码

服务器报错,也应该返回状态码告诉客户端是什么错误

响应对象主要有三种形式:

HttpResponse() 回复字符串 默认响应状态码是200

render() 回复页面内容 默认响应状态码是200

redirect() 重定向 默认响应状态码是302

如果发生什么问题,比如经过各种逻辑判断逻辑有误,参数不对等,服务端此时应该回复异常的状态码

(1)设置响应头键值对

def code(request):

ret = HttpResponse(“状态码”)

ret[‘name’] = “jinghao” # 添加响应头键值对 #会调用HttpResponse setattr方法,在setattr()方法中对响应头键值对进行了封装

return ret

浏览器访问查看

响应数据在前端都能拿到,拿出来就可以做一些处理

比如用户名密码认证成功之后,比如加个键值对 isLogin=True

响应头在客户端拿到以后,再登录某个页面之后,可以携带这个数据,后台拿到这个数据之后,就知道该用户已经登录了,不用重新登录

(2)设置响应状态码

#设置状态码

def code(request):

ret = HttpResponse(“状态码”)

ret[‘name’] = “jinghao” # 添加响应头键值对 #HttpResponse setattr

ret.status_code = 404 # 修改状态码

return ret

正常状态下不需要设置状态码,但为了接口规范,一些情况下需要设置状态码

render HttpResponse Redirect 三种响应方式都可以修改响应状态码

4.CBV模式

FBV(function base views) 就是在视图里使用函数处理请求。

之前都是FBV模式写的代码,所以就不写例子了。

CBV(class base views) 就是在视图里使用类处理请求。

Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。

所以Django在后来加入了Class-Based-View。可以让我们用类写View。

这样做的优点主要下面两种:

提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)

可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性

如果用class-based view写的话,就是下面这样

(1)CBV模式写法,先引入类

from django.views import View

#自己写的类要继承View类

class BookView(View):

# 通过反射获取到请求方法对应的类中的方法来执行

#需要什么类型的请求。就定义什么方法,比如get,post,方法名固定

def get(self,request):

return HttpResponse(‘book’)

# 需要处理什么请求方法,就写对应名称的方法

根据其继承的类,我们可以看到,原码中支持的八种方法类型,我们在类中写的方法必须是这八种方法其中的一种,不然会报错

Django的url是将一个请求分配给可调用的函数的,而不是一个class。

针对这个问题,class-based view提供了一个as_view()静态方法(也就是类方法),调用这个方法,会创建一个类的实例,

然后通过实例调用dispatch()方法,dispatch()方法会根据request的method的不同调用相应的方法来处理request(如get() , post()等)。

到这里,这些方法和function-based view差不多了,要接收request,得到一个response返回。如果方法没有定义,会抛出HttpResponseNotAllowed异常。

原码部分

def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    # defer to the error handler. Also defer to the error handler if the
    # request method isn't on the approved list.
    if request.method.lower() in self.http_method_names: #get
        # ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs) 就是get  # HttpResponse('ok')

dispatch方法就是为了获取我们在类中写的方法,然后返回方法执行返回结果 

注意:使用CBV时,urls.py中也做对应的修改:

from django.contrib import admin
from django.urls import path
from login import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.login),
    # path('login/', views.login),
    # path('logininfo/', views.logininfo),
    path('login2/', views.login2),
    path('new/', views.new),
    path('code/', views.code),
    path('book/', views.BookView.as_view()),  注意,这里是views.类名.as_view()
]

我们继承的类View类中有as_view方法

浏览器访问

(2)CBV模式下传参

创建个文章类

使用get方法

如果想看2018年的文章

urls.py路径需要配置,year是变量名,需要再视图函数里面传进去

views视图函数需要传参year

浏览器访问

article/后面只要是个int类型的数字数字都可以访问

使用post方法提交表单,post方法也要传参

form表单使用post方法,在当前页面提交

浏览器显示

输入一个用户名提交

后端可以通过request.POST获取提交数据。获取的是QueryDict字典类型,字典的值是列表


相关文章
|
1天前
|
监控 安全 应用服务中间件
python中Django入门(四)
python中Django入门(四)
31 0
|
1天前
|
前端开发 JavaScript BI
Django教程第5章 | Web开发实战-数据统计图表(echarts、highchart)
使用echarts和highcharts图表库实现折线图、柱状图、饼图和数据集图
71 2
|
1天前
|
缓存 API 数据库
Django中的视图装饰器:扩展视图功能的利器
【4月更文挑战第15天】Django视图装饰器用于扩展视图功能,如权限验证、缓存控制和日志记录。它们是Python的高级特性,能不修改原始函数代码就添加新功能。Django提供内置装饰器,如`@login_required`(强制用户登录)、`@cache_page`(缓存视图输出)和`@csrf_protect`(CSRF保护)。同时,开发者可自定义装饰器,例如上面的`timing_decorator`用于记录视图执行时间。使用装饰器时要注意性能影响、执行顺序和参数处理。装饰器增强了代码复用性和可维护性。
|
1天前
|
缓存 数据库 开发者
Django视图中的缓存机制:提升页面加载速度
【4月更文挑战第15天】本文介绍了Django的缓存机制在提升页面加载速度中的作用。Django提供视图缓存和片段缓存,通过`cache_page`装饰器和`CacheMixin`实现视图级别的缓存,使用`{% cache %}`模板标签实现页面片段缓存。开发者可选择不同的缓存后端,并在设置中配置缓存参数。同时,注意合理控制缓存粒度、及时更新和管理缓存,以优化用户体验和网站性能。
|
1天前
|
测试技术 数据库 开发者
Django自动化测试入门:单元测试与集成测试
【4月更文挑战第15天】本文介绍了Django的自动化测试,包括单元测试和集成测试。单元测试专注于单个视图、模型等组件的正确性,而集成测试则测试组件间的交互。Django测试框架提供`TestCase`和`Client`进行单元和集成测试。通过编写测试,开发者能确保代码质量、稳定性和应用的正确协同工作。运行测试使用`python manage.py test`命令,建议将其纳入日常开发流程。
|
1天前
|
中间件 数据安全/隐私保护 Python
python中Django入门(三)
python中Django入门(三)
19 0
|
1天前
|
前端开发 JavaScript Shell
python中Django入门(二)
python中Django入门(二)
14 0
|
1天前
|
SQL Shell 数据库
python中Django入门(一)
python中Django入门(一)
29 0
|
1天前
|
安全 数据库 开发工具
Django实战:从零到一构建安全高效的Web应用
Django实战:从零到一构建安全高效的Web应用
64 0
|
1天前
|
存储 数据库 Python
Django教程第6章 | web开发实战-文件上传(导入文件、上传图片)
web应用实战:导入文件解析到DB,上传图片【2月更文挑战第25天】
59 0
Django教程第6章 | web开发实战-文件上传(导入文件、上传图片)
http://www.vxiaotou.com