首先需要理解django对于url的路由
django对于url的路由.pngurl匹配问题
- 一般我们都会在app下新建一个urls.py文件,将每个请求路由到具体的app中处理。因为路由是从上到下依次匹配,如果匹配到就停止匹配,如果有很多app就很容易发生冲突
假如请求为:http://127.0.0.1:8000/api/recommendation/getNewsList?param=XXX
- Django在接收到一个请求时,从主路由文件中的urlpatterns列表中以由上至下的顺序查找对应路由规则,如果发现规则为include包含,则再进入被包含的urls中的urlpatterns列表由上至下进行查询。
首先在项目的urls.py将请求通过include函数下发到指定的app(这里的app为demo)中去
# 项目的urls.py
urlpatterns = [
path('admin/', admin.site.urls),
#路由转发
path('api/recommendation/',include('demo.urls')),
]
在app中新建一个urls.py,然后处理路由过来的请求
#app的urls.py
app_name = "demo"
urlpatterns = [
path('getNewsList', views.get_user_news_list, name="newsList"),
]
请求解析
HTTP协议向服务器传参有几种途径?
- 提取URL的特定部分,如/weather/beijing/2018,可以在服务器端的路由中用正则表达式截取;
- 查询字符串(query string),形如key1=value1&key2=value2;
- 请求体(body)中发送的数据,比如表单数据、json、xml;
- 在http报文的头(header)中。
url规则一
- 要从url捕获值,需要使用尖括号<>
- 捕获的值可以加类型转换器 例如,用于 < int:year >捕获整数参数
- 无需加斜杠,因为每个URL都有该斜杠 例如articles,不是/articles
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>/', views.year_archive),
path('articles/<int:year>/<int:month>/', views.month_archive),
path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),]
- 请求/articles/2005/03/匹配列表中的第三个条目。Django将调用该函数 。views.month_archive(request, year=2005, month=3)
- /articles/2003/会匹配列表中的第一个模式,而不是第二个,因为这些模式是按顺序测试的,而第一个是第一个通过的测试。随意利用命令来插入类似这样的特殊情况。在这里,Django将调用该函数 views.special_case_2003(request)
- /articles/2003 不会与任何这些模式匹配,因为每种模式都要求URL以斜杠结尾。
- /articles/2003/03/building-a-django-site/将匹配最终模式。Django将调用该函数 。views.article_detail(request, year=2003, month=3, slug="building-a-django-site")
其中每个参数转换器如下
-
str-匹配任何非空字符串,但路径分隔符除外'/'。如果表达式中不包含转换器,则为默认设置。
-
int-匹配零或任何正整数。返回一个int。
-
slug-匹配由ASCII字母或数字以及连字符和下划线字符组成的任何条形字符串。例如, building-your-1st-django-site。
-
uuid-匹配格式化的UUID。为防止多个URL映射到同一页面,必须包含破折号并且字母必须小写。例如,075194d3-6885-417e-a8a8-6c931e272f00。返回一个 UUID实例。
-
path-匹配任何非空字符串,包括路径分隔符 '/'。这样,您就可以与完整的URL路径进行匹配,而不仅仅是与URL路径的一部分进行匹配str。
-
在path中不需要单独给出请求参数
也可以通过正则表达式,如下:
#请求
url(r'^weather/([a-z]+)/(\d{4})/$', views.weather)
#处理函数
def weather(request, city, year):
print('city=%s' % city)
print('year=%s' % year)
return HttpResponse('OK')
url规则二
- 形如http://XXXX /?a=1&b=2&a=3 的请求
def qs(request):
a = request.GET.get('a')
b = request.GET.get('b')
alist = request.GET.getlist('a')
print(a) # 3
print(b) # 2
print(alist) # ['1', '3']
return HttpResponse('OK')
url规则三
- 前端发送的表单类型的请求体数据
def get_body(request):
a = request.POST.get('a')
b = request.POST.get('b')
alist = request.POST.getlist('a')
print(a)
print(b)
print(alist)
return HttpResponse('OK')
request.POST只能用来获取POST方式的请求体表单数据。
url规则四
- 非表单类型的请求体数据,Django无法自动解析,可以通过request.body属性获取最原始的请求体数据,自己按照请求体格式(JSON、XML等)进行解析。request.body返回bytes类型。
例如要获取请求体中的如下JSON数据
{"a": 1, "b": 2}
可以进行如下方法操作:
import json
def get_body_json(request):
json_str = request.body
json_str = json_str.decode() # python3.6 无需执行此步
req_data = json.loads(json_str)
print(req_data['a'])
print(req_data['b'])
return HttpResponse('OK')
网友评论