vscode 快速打印console.log

阅读 101

2023-11-16

文章目录

前言

视图函数的返回值

为什么视图函数需要返回一个HttpResponse对象?

可以用一个例子来看看:(前提先配置好路由)

在这里插入图片描述

	def index(request):
		return None

然后我们直接开启服务,访问这个路由地址
在这里插入图片描述


三板斧源码大概注解

而其中HTML的三种响应方式返回的都是一个HttpResponse对象(可以查看源码)

	'''源码大概注解展示'''
	
	class HttpResponse(HttpResponseBase):
		'''括号内直接跟一个具体的字符串作为响应体'''
	    streaming = False  # 表示是否支持流式传输
	    
	    # 初始化HttpResponse实例,设置响应的内容
	    def __init__(self, content=b'', *args, **kwargs):
	        super(HttpResponse, self).__init__(*args, **kwargs)
	        # Content is a bytestring. See the `content` property methods.
	        self.content = content
	    ......

	====================================================================================
	
	def render(request, template_name, context=None, content_type=None, status=None, using=None):
	'''
		request:用于生成响应的请求对象
		template_name:要使用的模版的完整名称,可选的参数
		context:添加到模版上细纹的一个字典。默认是空字典。如果字典中的某一个值是可调用的,视图将在渲染模版之前调用它。
		render方法就是将一个模版页面中的模版语法进行渲染,最终渲染成一个html页面作为响应体
	'''
		# 使用Django的模版引擎加载和渲染模版
	    content = loader.render_to_string(template_name, context, request, using=using)
	    # 返回一个HttpResponse对象加括号调用HttpResponse的类
	    return HttpResponse(content, content_type, status)

	====================================================================================
	
	def redirect(to, *args, **kwargs):
		'传递要重定向的一个硬编码的URL或者路由'
	    if kwargs.pop('permanent', False):
	    '如果参数中包含 'permanent',并且其值为 True,则使用 HttpResponsePermanentRedirect 类'
	        redirect_class = HttpResponsePermanentRedirect
	    else:
	    	'否则使用默认的 HttpResponseRedirect 类'
	        redirect_class = HttpResponseRedirect
	        
		'''
		这里返回一个HttpResponse对象加括号调用HttpResponse的类
		创建相应的重定向对象,将重定向目标设置为 to
		'''
	    return redirect_class(resolve_url(to, *args, **kwargs))
	'''
		这样的设计使得 redirect 函数能够支持两种类型的重定向:
		临时重定向(HttpResponseRedirect)和永久重定向(HttpResponsePermanentRedirect),
		具体取决于 'permanent' 参数的值。
	'''

三板斧的使用

HttpResponse

示例:

	from django.shortcuts import HttpResponse
	
	def my_custom_response(request):
	    # 一些逻辑处理后,生成自定义的响应内容
	    content = 'This is a custom response.'
	    # 使用HttpResponse类创建HTTP响应
	    response = HttpResponse(content, content_type='text/plain', status=200)
	    # 可以添加自定义的头部信息
	    response['Custom-Header'] = 'Some value'
	    return response

在这里插入图片描述

	from django.shortcuts import HttpResponse
	
	def index(request):
    response = HttpResponse()  # 实例化产生一个对象

    response.content = 'Lucky'  # 设置响应内容
    response.status_code = 404  # 设置响应状态码
    # 直接写出文本
    response.write('777777')
    # 一次性读取剩余字节,冲刷缓存区
    response.flush()
    return response

在这里插入图片描述


redirect

示例:

	from django.shortcuts import redirect
	def my_redirect_view(request):
	    # 某些逻辑处理后,决定重定向到另一个URL
	    new_url = '/index/'
	
	    # 使用redirect函数生成重定向响应
	    return redirect(new_url)

在这里插入图片描述


render

示例:

	from django.shortcuts import render

	def my_view(request):
	    # 从数据库获取数据或进行其他逻辑处理
	    data = {'foo': 'bar'}
	
	    # 使用render函数渲染模板,并将数据传递给模板
	    return render(request, 'my_template.html', {'data': data})

总结:


JsonResponse对象

视图函数返回json格式的数据

  • 方法一
    json序列化形式
	import json
	def Myjson(request):
	    user_dict = {'name':'oscar','age':18,'hobby':['唱','跳','rap']}
	    '''如果数据中有中文会进行编码,如果不想它编码就直接设置ensure_ascii=False即可'''
    	data = json.dumps(user_dict,ensure_ascii=False)
	    return HttpResponse(data)

在这里插入图片描述

  • 方法二
    JsonResponse序列化形式
	'需要先导入JsonResponse模块'
	from django.http import JsonResponse
	
	def js(request):
	    user_dict = {'name': 'oscar', 'age': 18, 'hobby': ['唱', '跳', 'rap']}
	    return JsonResponse(user_dict)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


form表单携带文件数据

注意事项:

  • enctype属性需要由默认的urlencoded变成form/data(enctype=“multipart/form-data”)

  • method属性需要由默认的get变成post
    (目前还需要考虑的是 提交post请求需要将配置文件中的csrf中间件注释)

  • 如果form表单上传文件 后端需要在request.FILES获取文件数据 而不再是POST里面

首先需要建立一个HTML页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="" method="post" enctype="multipart/form-data">
    	<input type="text" name="text" placeholder="请输入文字">
        <input type="file" name="myfile">
        <input type="submit" value="提交">
    </form>
</body>
</html>

然后再建立路由和视图函数

	'路由文件'
	from app import views
	urlpatterns = [
	    url(r'^func/', views.func),
	]

	'视图文件'
	def func(request):
	    print(request.POST)
	    return render(request,'index.html')

配置后这些后,直接访问对应的路由,然后点击选择文件后提交

在这里插入图片描述

结果发现仅仅只是接收到了普通文本数据,并没有接收到文件数据
在这里插入图片描述

这时我们可以使用request.FILES来获取文件数据

	def func(request):
	    print(request.POST)
	    print(request.FILES)
	    return render(request,'index.html')

在这里插入图片描述


然后我们可以通过对获取到的文件数据进行写入文件中

  • 首先我们从上述过程中,可以知道,得到的数据格式是字典格式,所以我们可以通过字典的方式取出数据
	def func(request):
	    if request.method == 'POST':
	        file_info= request.FILES.get('myfile')
	        print(res)
	    return render(request,'index.html')

在这里插入图片描述

  • 拿到名字后就可以通过写入文件的方式写入文件数据了,但是要注意需要使用wb模式写入,因为wb模式可以把二进制数据转换成str格式。
	def func(request):
	    if request.method == 'POST':
	        # print(request.FILES)
	        file_info = request.FILES.get('myfile')
	        
	        with open(file_info.name,'wb')as f: 
	        '避免文件数据过大,使用一行一行的写入'
	            for line in file_info:
	                f.write(line)
	
	    return render(request,'index.html')

在这里插入图片描述


request对象方法

1.获取请求方式POST/GET
request.method
一个字符串,表示请求使用的HTTP 方法。必须使用大写。

2.request.POST
获取POST请求提交普通的键值对数据 一个类似于字典的对象,如果请求中包含表单数据,则将这些数据封装成

3.获取GET请求
request.GET
获取GET请求	一个类似于字典的对象,包含 HTTP GET 的所有参数

4.获取文件
request.FILES
一个类似于字典的对象,包含所有的上传文件信息。
FILES 中的每个键为<input type="file" name="" /> 中的name,值则为对应的数据。
注意,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况下才会包含数据。否则,FILES 将为一个空的类似于字典的对象。

5.原生的浏览器发过来的二进制数据
request.body  
一个字符串,代表请求报文的主体。在处理非 HTTP 形式的报文时非常有用,
  例如:二进制图片、XML,Json等。

6.拿到路由
request.path 
个字符串,表示请求的路径组件(不含域名)

7.拿到路由
request.path_info

8.能过获取完整的url及问号后面的参数 
request.get_full_path() 

FBV与CBV

FBV

CBV

Python是一个面向对象的编程语言,如果只用函数来开发,很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:

  1. 提高代码的复用性,可以使用面向对象的技术。
  2. 根据不同的类方法处理不同的HTTP请求,而不是通过很多if判断,提高代码可读性。

如果要写一个处理GET请求的view,FBV是这样写的

	路由文件
	from app import views
	urlpatterns = [
    	url(r'^test/',views.test)
	]

	视图文件
	from django.shortcuts import HttpResponse
	def test(request):
	    if request.method == 'GET':
	        return HttpResponse('this is test')

使用CBV是这样写的

	路由文件
	from app import views
	urlpatterns = [
    	url(r'^Mytest/',views.My_test.as_view()),
	]

	视图文件
	from django.shortcuts import HttpResponse
	from django.views import View
	class My_test(View):
	    def get(self,request):
	        return HttpResponse('this is test')

CBV类中的不能随意的定义函数,只能使用八大请求方式

	'get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'
	'所有的类必须继承django的view类'
	from django.views import View
	
	class MyLogin(View):
	    # 类里面的方法名字不能够随便写,目前只能写get post等
	    # 访问这个地址必须是get请求方式
	    def get(self, request):
	        # get() takes 1 positional argument but 2 were given
	        print("get")
	        return HttpResponse("get")
	
	    # 访问这个方法必须是psot请求方式
	    # 通过form表单发送post请求
	    # 出了form表单,我们还可以使用工具来模拟
	    def post(self,request):
	        print("post")
	        return HttpResponse("post")

	postman的官网地址:https://www.postman.com/downloads/
	apizza的挂网地址:http://www.apizza.net/

CBV的源码解析

在这里插入图片描述

	urlpatterns = [
	    url('^index/', views.index.as_view())
	    # 手动调用后会拿到view方法的返回值。变成了以下的样子
	    url('^index/', views.index.view)
	    # 那么此时Django会帮助我们调用一次这个方法,并且传递一个request请求过去。
	]

view方法解析
那么我们再看看view方法干了些什么事情:只看红框内容即可
在这里插入图片描述

  • 首先是根据cls实例化出一个对象了(这cls就是我们在视图内定义的类)
  • 将request请求给这个对象作为属性
  • 而args、kwargs则是防止有名分组或无名分组,用于接收分组产生的值。也一同赋给这个对象。
  • 调用这个对象下面的dispatch方法,并将Django传递的参数一并传递过去了

dispatch方法解析
再分析一下dispatch方法的作用:只关注红框内容即可
在这里插入图片描述

request.method.lower()将请求的方法变成小写的字符串

主要就是判断:发送请求的方法是否符合正常HTTP请求

	http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

如果符合的话:使用反射通过拿到的字符串去对象里查找相同名称的函数。比如:

	class index(View):
		def get(self,request):
			return HttpResponse('from GET')

	self = index类实例化的对象,并且拥有request、args、kwargs等属性
	# 等同于:如果request.method.Lower()是get的话,拿到get方法的函数对象
	handle = getattr(self,'get',None) # 地三个参数则是没有找到get方法或属性返回的

	handle = get函数对象

	handle(request,*args,**kwargs) # 等同于:get(self,request,*args,**kwargs)

调用时将request请求、一些额外参数都传递给了我们定义的类里面的get方法

演示:不定义人任何处理请求的函数

	class index(View):
    	pass

在这里插入图片描述
浏览器得不到Django响应的任何数据!

get方法需要返回一个HttpResponse对象,没有返回的话,则页面报错

	class index(View):
		def get(self,request):
			print('......')

在这里插入图片描述
注意:如果类里面没有定义处理对应请求的函数,浏览器得不到响应,专门处理某个请求的函数名一定要与请求名一致。

总结

而CBV的实现通过上述源码的分析也可以看出来,大致就是通过URL执行类里面的view方法,再通过其内部的dispatch方法进行分发处理,将浏览器请求交给我们的类里面对应的方法进行处理。

精彩评论(0)

0 0 举报