序言
在最近的项目中,分别使用了两种类似的获取url参数的视图函数,这两个视图函数的作用是相同的,都是跳转详情的功能,这个获取跳转的内容,便是本次要获取的参数,所以问题就来了,怎么获取这个参数,比如文章的唯一 id 号,要怎么获取,django 提供了一个最直接的方法,那便是正则匹配 url ,即在 urls.py 文件内的urlpatterns = [ ] ,搞正则匹配,这其中匹配到的第一个参数,便是视图函数的第一个参数,以此类推,匹配到第二个参数,便是视图函数的第二个参数。。。
1、第一种参数匹配的方法
1.1、 正则匹配 url 参数
eg:
urls.py 演示 (但其实加不加 r 符号,都一样,下面的 urls.py 演示,要的只是 \?
规避问号截断问题)
# urls.py
from myapp.views import *
urlpatterns = [
url('^finddetail\?find=(.*)$', mydetail),
]
django演示模板:
{% for i in acticles %}
<a href="/finddetail%3Ffind={{ i.article_id }}" target="_blank">
{% endfor %}
特别注意 %3F
这个东西,url 解码后就是 \?
问号,浏览器默认都会将字符串,使用url 编码函数去将任何的 url 链接编码,在进行传送,所以此时虽然已经是 %3F 编码,但在django 端会对其进行url 解码,获取 \?
问号,以此判断 url \?
后面是一个参数
还有需要注意的一点是,笔者上面的 url(‘^finddetail?find=(.*)$’, mydetail), 里面并没有配置 r 符号(r’ ’ 或 r" " ,默认双引号,单引号内的反斜杠 \ 不会将任意字符转义,比如 \n 会变成换行符),也就是说,这里笔者是用了一个任意字符来规避掉 ?
无法被 url 的正则匹配的问题,django这里的url问号,好像会被截断,问号后面不被继续匹配了,无论笔者怎么测试,问号是一个截断点,所以笔者无奈想出了这个方法,不过后面找到了正常的方法了。
views.py 演示
# 文章详情页
def mydetail(request, article_id):
context = {}
return render(request, 'article/article_detail.html', context)
好了,上面是获取 url get 方法参数最简单的方法了,下面介绍比较深入的方法。
2、第二种参数匹配的方法(推荐)
2.1、配置 app 的 url 命名空间
如果不太理解命名空间的,大致先理解为一个 url 路由的别名就行了,或者可以先去搜索资料理解下,再回来看。
首先得有一个 index.html ,比如里面有一个跳转文章详情的 a 标签,如下所示:
index.html
模板演示:
<a href="{% url 'pcweb:new_mydetail' %}?find={{ article.id }}">测试查找文章123456
</a>
然后配置主路由文件 (有settings.py文件的那个文件夹下的 urls.py 文件)namespace=命名空间名
# urls.py
urlpatterns = [
url('^pcweb/', include(('article.urls', 'pcweb'), namespace='pcweb')),
]
再配置子路由文件 (文章 app 下的 urls.py 文件)
# urls.py
from myapp.views import *
urlpatterns = [
url(r'^finddetail$', new_mydetail, name='new_mydetail'),
]
再配置文章详情视图 ,views.py 文件演示:
# views.py
def new_mydetail(request):
article_id = request.GET.get('find')
article = Article.object.filter(id=article_id) # orm 获取文章对象
context = {'article': artilce}
return render(request, 'article/article_detail.html', context)
article_detail.html
文章详情模板演示:
<span>{{ article.title }}</span>
<span>{{ article.content }}</span>
如果理解了,就应该看懂 ? 问号后的 find
url 默认 ? 问号后,就是一个参数,这是一个规则
所以在 urls.py 文件内,完全不需要按照第一种 url 参数匹配方法那样,去设置正则匹配,只需要 request.GET.get()
方法去获取 get 方法参数。
最后 index.html 模板渲染完成后的 a 标签内的 url 如下(查找的文章 id 为123456):
<a href="/pcweb/finddetail?find=123456">测试查找文章123456</a>
总结
笔者个人建议用第二种方法来配置路由比较好,维护起来也方便(url命名空间的便利性),还有看起来比较正统些,应该说比较正常化。
还有一个比较重要的一点是,提升性能,虽然也没啥提升的。如果是第一种方法,那么django 框架会调用正则匹配函数,但是假如是第二种方法,笔者认为在request 请求的get方法中,会自带了一个存储好的参数,供request.GET.get()调用,那么调用正则匹配函数去匹配url参数,还是直接调用获取 url 参数,这两种当然是直接调用更快了。