飞行的猪哼哼

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一:前端传输参数的4种方式:
1:查询字符串的方式:

http://www.meiduo.site/list/115/1/?sort=price   中的?sort=price

2:请求体数据:
例如:表单,json
3:url路径的部分:

http://www.meiduo.site/detail/2/中的/2/

4:请求头数据:以键值对的方式存储。

二:提取查询字符串数据
获取请求路径中的查询字符串参数,形如:?k1=v1&k2=v2
可以通过request.GET属性获取,并返回QueryDict类型的对象
1:首先在视图中创建类来接收request,然后使用
request.GET.get(‘name’, ‘小明’)获取字符串中的数据和指定默认值。


class QSParamView(View):

    def get(self,request):

        name = request.GET.get('name','小明')
        age = request.GET.get('age','0')
        return http.HttpResponse("查询参数:name:%s age:%s" % (name,age))

2:注册子路由和总路由。

 path("querystring/",views.QSParamView.as_view()),
   path("",include("request_response.urls")),

3:出现的问题:
提取查询字符串参数不区分请求方式,即使客户端进行POST方式的请求,依然可以通过request.GET获取请求中的查询字符串参数。
QueryDict是由Django自己封装的一个数据类型,继承自python的字典Dict它被定义在django.http.QueryDict中,它专门用来存储请求中提取的查询字符串参数和请求体参数
即,HttpRequest对象中的属性GET、POST都是QueryDict类型的数据。

4:推荐使用get的方式取值,因为[]的方式一旦找不到,程序就会报错。

# 如果键不存在则返回None值,可以设置默认值进行后续处理
query_dict.get('键',默认值)
# 可简写为:
query_dict['键']

三:提取请求体数据:
3.1:表单类型请求体数据(Form Data)
前端发送的表单类型的请求体数据,可以通过request.POST属性获取,并返回QueryDict对象。
request.POST只能用来获取POST表单发送的请求体数据

# 表单类型请求体数据
class FormDataParamView(View):

    def post(self, request):

        username = request.POST.get("username")
        password = request.POST.get("password")

        return http.HttpResponse("表单数据请求提数据是:username:%s password:%s" % (username,password))
 path("formdata/", views.FormDataParamView.as_view()),

3.2:非表单类型请求体数据(Non-Form Data):JSON
非表单类型的请求体数据,Django无法自动解析,可以通过request.body属性获取最原始的请求体数据,然后自己按照具体请求体原始数据的格式(JSON等)进行解析。
request.body获取的是bytes类型的请求体原始数据

lass FormDataParamView1(View):

    def post(self, request):

        json_str = request.body
        print(json_str)
        json_dict = json.loads(json_str)

        username = json_dict.get("username")
        password = json_dict.get("password")

        return http.HttpResponse("表单数据请求提数据是:username:%s password:%s" % (username,password))
 path("json/", views.FormDataParamView1.as_view()),

四:URL路径参数:提取URL路径中的特定部分数据
在定义路由时,可以从URL中获取特定部分的路径参数
Django的路由系统会将提取的路径参数传递到视图的内部
path()和re_path()都可以提取路径参数

4.1:path()提取路径参数:
注意:路由中提取路径参数时,使用的关键字,必须跟视图中参数名一致
测试path()提取普通路径参数:http://127.0.0.1:8000/url_param1/18/提取里面的18
注意:get 方法需要多一个参数。

class  URLParam1View(View):

    def get(self,request,age):
        return http.HttpResponse("路径中的参数是:%s" % age )
path('url_param1/<int:age>/',views.URLParam1View.as_view())

问题:如果存在多个参数呢?

class  URLParam1View(View):

    def get(self,request,age1,age2):
        return http.HttpResponse("路径中的参数是:%s,%s" % (age1,age2) )
path('url_param1/<int:age1>/<int:age2>/',views.URLParam1View.as_view())

访问地址:http://127.0.0.1:8000/url_param1/18/19/
问题2:实现需求1时提取age数字的int:age是什么?
答案:路由转换器
Django默认封装了一些正则表达式,用于在path()中要提取路径参数时使用。
路由转换器的位置:django.urls.converters.py

DEFAULT_CONVERTERS = {
    'int': IntConverter(), # 匹配正整数,包含0
    'path': PathConverter(), # 匹配任何非空字符串,包含了路径分隔符
    'slug': SlugConverter(), # 匹配字母、数字以及横杠、下划线组成的字符串
    'str': StringConverter(), # 匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
    'uuid': UUIDConverter(), # 匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00
}

问题3:http://127.0.0.1:8000/url_param2/18500001111/提取路径中的手机号18500001111,默认的路由转换器中,没有专门用来匹配手机号的路由转换器,所以在使用path()实现需求2时,就无法直接使用默认的路由转换器。

解决方案一:自定义路由转换器
1:定义视图函数
2:在工程根目录下,新建converters.py文件,用于自定义路由转换器
3:在总路由中,注册自定义路由转换器
4:在子路由中使用自定义路由转换器

class  URLParam2View(View):

    def get(self,request,phone_num):
        return http.HttpResponse("路径中的参数是:%s" % phone_num)

class MobileConverter:
    # 注意这个regex不能起别的名字
    regex = '1[3-9]\d{9}'

    # 这里的方法名也不能修改
    def to_python(self,value):
        # 将匹配到的结果传递到视图内部使用
        return int(value)

    def to_url(self,value):
        # 将匹配到的结果反向解析传值使用
        return str(value)
from django.contrib import admin
from django.urls import path, include, register_converter

# 在总路由中注册自定义转换路由
from converters import MobileConverter

register_converter(MobileConverter, 'mobile')

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

]
path('url_param2/<mobile:phone_num>/', views.URLParam2View.as_view()),

分析路由解析流程:当发送http://127.0.0.1:8000/url_param2/18500001111/时需要和总路由进行匹配,总路由注册了自定义的转换器,并且给子路由起别名register_converter(MobileConverter, 'mobile'),当url进入子路由的时候,转换器和地址进行匹配path('url_param2/<mobile:phone_num>/', views.URLParam2View.as_view()),当匹配成功转换器的to_python方法将结果传入视图中的URLParam2View。

解决方案二:re_path()提取路径参数(复杂路径推荐使用)

class  URLParam3View(View):

    def get(self,request,phone_num):
        return http.HttpResponse("路径中的参数是:%s" % phone_num)
re_path(r'^url_param3/(?P<phone_num>1[3-9]\d{9})/$', views.URLParam3View.as_view()),

五:请求头:
以通过request.META属性获取请求头headers中的数据,request.META为字典类型。
常见的请求头如:

CONTENT_LENGTH – The length of the request body (as a string).
CONTENT_TYPE – The MIME type of the request body.
HTTP_ACCEPT – Acceptable content types for the response.
HTTP_ACCEPT_ENCODING – Acceptable encodings for the response.
HTTP_ACCEPT_LANGUAGE – Acceptable languages for the response.
HTTP_HOST – The HTTP Host header sent by the client.
HTTP_REFERER – The referring page, if any.
HTTP_USER_AGENT – The client’s user-agent string.
QUERY_STRING – The query string, as a single (unparsed) string.
REMOTE_ADDR – The IP address of the client.
REMOTE_HOST – The hostname of the client.
REMOTE_USER – The user authenticated by the Web server, if any.
REQUEST_METHOD – A string such as "GET" or "POST".
SERVER_NAME – The hostname of the server.
SERVER_PORT – The port of the server (as a string).

案例:

class HeadersParamView(View):
    """测试提取请求头参数"""

    def get(self, request):
        # 获取请求头中文件的类型
        ret = request.META.get('CONTENT_TYPE')
        print(ret)
        return http.HttpResponse('OK')
path("head/",views.HeadersParamView.as_view()),
posted on 2020-08-27 19:27  飞行的猪哼哼  阅读(63)  评论(0)    收藏  举报