Django中的url
0X00 url的源头
使用django-admin startproject test_project
创建一个新的Django项目之后在settings.py
中可以找到一个配置项ROOT_URLCONF
,默认情况下值为项目目录下的urls
,也就是test_project.urls
。
默认情况下这个urls.py
的内容大致是这样的
1 | """learn_django URL Configuration |
这里就是根目录了,新项目使用python manage.py runserver
启动之后访问http://127.0.0.1:8000/
就是访问到这个url的根路由了,默认情况下有一个admin/
可选,也就是Django自己的后台管理页面。Django所有的url都是从这个文件发散出去的,urlpatterns
里除了将url路由至view
就是其他的子url配置。换句话说,通常情况下Django中所有url最终都应该被路由到View上才对。
0X01 路由到子url和view
上面提到通常情况下Django中所有url最终都应该被路由到View上,那就来看一下究竟该怎么做。现在有一个项目,项目中有一个app叫student
是用来管理一些学生信息的,app中有一个views.py
,具体内容就暂时不列出了,在此处关系不大;还有一个urls.py
,内容是这样的
1 | from django.urls import path |
现在要来修改根的urls.py
了
1 | from django.contrib import admin |
现在就是这样的,如果访问http://127.0.0.1:8000/admin
还是之前的DjangoAdmin默认管理页面没问题,如果访问http://127.0.0.1:8000/student/
的话就是到StudentView
而http://127.0.0.1:8000/student/exam/
就是ExamView
了。
0X02 参数与正则
url中常见的出现一些参数,一般来说参数分成两种:第一种是在path中作为路由的一部分,另一种是在后面以GET的查询参数方式出现例如/student?name=shawn&age__gt=16
这种。第二种方式比较简单,在传入到view后,从view的request.GET
就能取到了。但是也经常会遇到第一种,例如这样一个path/article/2019/11/20/why-linux
,可以猜测它指的是2019年11月20日的一篇名为’why-linux’的文章。那么这种该怎么取呢?其实很简单,在view里request.path.split('/')
然后取下标就行了(当然这很蠢且很不靠谱,但是还不失为一种方案哈哈哈哈)。
这种时候比较靠谱的方式是使用url中的参数,有一个子url配置如下
1 | urlpatterns = [ |
其中<int:year>
就是指的一个参数,前三个是整型参数,最后一个是字符串参数。我们知道view
中GET
方法的定义是def get(self, request, *args, **kwargs)
,那么其实后面的这个**kwargs
里就是这里传进来的参数了,可以通过year, month, day, name = kwargs['year'], kwargs['month'], kwargs['day'], kwargs['name']
这种类似的方式来取到对应的值
还是上面这个例子,咱们知道年号一定是正整数,月份一定是112之间,日期一定是131之间(先不考虑闰年和大小月的问题,只是方便探讨url)。那上面这个例子中的url如果我传一个/article/0/666/233/test/
过去其实是没有意义的,所以需要一些简单的校验。那么众所周知,正则表达式非常适合做这种事情。下面来修改一下刚刚的这个url配置好了,修改后的配置Django就可以根据正则来匹配了。
1 | from django.urls import re_path |
Django在匹配的时候是按照
urlpatterns
这个列表的下标顺序来的,所一说如果先符合了上面的规则,即时再符合下面的规则也不会继续判断下去了。
0X03 DRF中的router.register
一般使用Django的同时也会使用Django REST framework了,所以也简单介绍一下在DRF中特有的一种路由方式好了。因为DRF中大量使用ViewSet
而非标准的Django View,所以可以使用DRF封装的下面这种方式来建立路由
1 | from rest_framework import routers |
虽说是叫做
router
不过翻译成路由器总是有点怪怪的,哈哈哈