Django请求到响应的流程

273 阅读3分钟
mindmap
	root((请求响应))
		请求到响应的流程
		HttpRequest
			请求方式
				get、post
			请求头
				REMOTE_ADDR、HTTP_USER_AGENT
			获取请求参数
				GET、POST、COOKIES、FILE
		响应对象
			HttpResponse、JsonResponse...
				如何响应HTML模板
			响应对象之间的关系

请求到响应的流程

  1. 当用户再浏览器中,去访问URL的时候会发送一个请求到django内置的服务器;
  2. 服务器接收到请求之后,通过urls的规则找到对应的视图函数处理,并返回结果发送给浏览器
  3. 浏览器解析结果并展示
graph TD;
浏览器--访问服务器端口URL-->django内置服务器
django内置服务器 --得到响应-->浏览器

请求对象HttpRequest

本质上是Django框架写好的一个类,将我们发过来的每一次请求封装成HttpRequest对象;当我们在使用视图函数时的request参数,其实就是HttpRequest类的一个实例

请求方式method

GET、POST

def hello_view(request):
    method = request.method

请求头META/headers

  • REMOTE_ADDR

    请求IP地址

  • HTTP_USER_AGENT

    用户请求终端信息

def hello_view(request):
    ua = request.META.get('HTTP_USER_AGENT',None)
    或
    ua = request.headers['USER_AGENT']

获取请求参数

  • GET:get请求参数

  • POST:post请求参数

  • COOKIES:cookies信息

  • FILES:文件信息

    def hello_view(request):
      name = request.GET.get('name', None)
      name = request.POST.get('name', None)
      name = request.COOKIES.get('name', None)
      name = request.FILES.get('name', None)
    

响应对象

HttpResponse

  • status

    设置HTTP响应状态码

  • status_code

    查看HTTP响应状态码

  • content_type

    设置响应的类型

    常见类型:

    • text/html:超文本标记语言文本(HTML)
    • text/plain:普通文本
    • text/xml:XML文档
    • image/png、image/jpeg、image/gif:图片或图形
    • application/json:json数据类型
  • write()

    写入响应内容

def hello_view(request):
  res = HttpResponse('响应内容',status=201,)
  res.status_code = 202
  print("查看响应状态码==>",res.status_code)
  return res

如何响应HTML

响应HTML内容到浏览器的原理

  1. 读取HTML文件
  2. 替换HTML中的特殊字符
  3. 发送给浏览器
  1. 在视图函数中定义视图函数
def hello_html_template(request):
    templ_name = 'hello.html'
    html = render_to_string(template_name=templ_name)
    或
    html = render(templ_name)
    return HttpResponse(html)
  1. 配置解析模板路径
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',  # django自带的模板引擎
        'DIRS': [BASE_DIR / 'hello/templates'],  # 模板路径
        'APP_DIRS': True,  # 是否可以使用新建模块下的templates
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

JsonResponse

def hello_view(request):
  res = JsonResponse({
    "name":"lcx",
    "age":"18",
  })

  return res

HttpResponseRedirect

重定向响应对象

  1. 定义路由
path('404/', no_data_404,name="no_data_404"),
  1. 定义视图
def hello_view(request,artictle_id):
  if artictle_id < 1000:
    return HttpResponseRedirect('hello/404/')
  
  return HttpResponse('非404页面')

def no_data_404(request):
  """404页面"""
  return HttpResponse('404')

FileResponse

def hello_view(request):
  res = FileResponse(open("myfile.png","rb"))

  return res

响应对象之间的关系

HttpResponse:主要响应文本之类的内容;如字符串、html、json

StreamingHttpResponse:主要响应二进制流之类的内容;如图片

graph TD;
 root(HttpResponse)--> A(HttpResponse) & B(StreamingHttpResponse)
 A-->JsonResponse
 B-->FileResponse

获取URL参数

  • 获取URL中指定类型参数

    1. 定义规则
    path('article/<int:month>/', hello_article_list),
    
    1. 定义视图函数
    def hello_article_list(request, month):
        html = f'''
        <html>
            <body>
                <h1 style="color:red" > hello article_list:{month}!</h1>
            </body>
        </html>
        '''
        return HttpResponse(html)
    
  • 获取URL中正则匹配的参数

    1. 定义规则
    re_path(r'^article/(?P<month>0?[1-9]1[012])/$', hello_article_list),
    
    1. 定义视图函数
    path('article/<int:month>/', hello_article_list),
    
    def hello_search(request):
        name = request.GET.get('name', None)
        html = f'''
        <html>
            <body>
                <h1 style="color:red" > hello search:{name}!</h1>
            </body>
        </html>
        '''
        return HttpResponse(html)
    

知识支撑

更好的重定向方式

  • 方式一
# 定义规则
path('404/', no_data_404,name="no_data_404"),

# 定义视图
def hello_view(request,artictle_id):
  if artictle_id < 1000:
    return redirect("no_data_404") # 支持视图名称
  	return redirect("hello/404/")	 # 支持规则
  	return redirect("http://x.com") # 支持外部链接
  
  return HttpResponse('非404页面')

def no_data_404(request):
  """404页面"""
  return HttpResponse('404')
  • 方式二
# 定义规则
path('404/', no_data_404,name="no_data_404"),

# 定义视图
def hello_view(request,artictle_id):
  if artictle_id < 1000:
    return HttpResponseRedirect(reverse('no_data_404'))
  
  return HttpResponse('非404页面')

def no_data_404(request):
  """404页面"""
  return HttpResponse('404')

渲染函数

render_to_string(template_name,context=None,reqiest=None,using=None)

template_name:模板名称

context:模板上下文对象(dict)

reqiest:请求对象

using:模板引擎名称

render(reqiest,template_name,context=None,context_type=None,status=None,using=None)

reqiest:请求对象

template_name:模板名称

context:模板上下文对象(dict)

context_type:MIME类型,默认text/html

status:HTTP状态码

using:模板引擎名称 最后一句

学习心得!若有不正,还望斧正。希望掘友们不要吝啬对我的建议。