logo头像
Snippet 博客主题

Python3 - Django中url使用及参数获取

URL管理

1、创建好Project后在全局配置文件中有一个urls.py这个模块,该模块主要管理本项目的全局url配置

2、每个APP也应该创建一个urls.py模块来管理自己APP下的url集(可选)

全局urls.py配置

主要注意的是

1、需要import include模块

2、在urlpatterns中添加app下的urls模块, namespace 参数可以防止不同app下的 url name

1
2
3
4
5
6
7
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^blog/', include('blog.urls', namespace="blog")),
]

APP下的urls.py

1、import django中url模块

2、import app中的views模块

3、需要注意的是url是以正则表达式来配置管理,访问web页面的url = 全局url+APP url

1
2
3
4
5
6
7
from django.conf.urls import url
from app import views

urlpatterns = [
url(r'^index/$', views.index, name="index"),
]
# 访问index页面url=http://localhost:8000/blog/index/


URL.py中的正则表达式

这里需要注意的是:

1、如果正则里面有()括号表示为分组,会自动将()括号里面的内容传到views.article_page视图中。

2、如果正则格式为:(?P<>) 表示为命名分组,在View视图里面或者template调用的时候,可以直接使用命名去调用


在url.py中我们可以使用正则表达式来匹配url

1
2
3
4
5
6
from django.conf.urls import url
urlpatterns = [
url(r'^$', views.index),
url(r'^article/(\d+)/(\d+)/$', views.catalog, name='catalog'),
url(r'^article/(?P<article_id>\d+)$', views.article_page),
]

注: 在Django2中可以path()定义路由, 但是如果要是用正则表达式, 仍需使用url()

1
2
3
4
5
from django.urls import path
urlpatterns = [
path(r'index/',views.index,name='index'),
path('article/<int:article_id>',viewsarticle_page),
]

在views.py中获取分组内的参数

1
2
3
4
5
def catalog(requset,chapter,title)
pass

def article_page(requset, article_id):
pass


Templates href格式

1
href="{% url 'app_name:url_name' param %}"

两种方式:

第一种

1
2
3
4
url(r'^blog/', include('blog.urls', namespace="blog"))
url(r'^article/(\d+)/(\d+)/$', views.catalog, name='catalog')

<a href="{% url 'blog:catalog' chapter title %}">

第二种

1
2
3
4
5
6
7
8
9
#第一步在app-url.py的url中添加一个name参数:name='app-views-func'

urlpatterns = [
url(r'^$', views.index),
url(r'^article/(?P<article_id>[0-9]+)$', views.article_page, name='blog-views-article_page'),
]

#第二步在Template中编写href
href="{% url 'blog-views-article_page' article_id %}"


使用querystring(查询字符串)

http://localhost/?a=3&b=5
跟在 ? 后面的就是查询字符串, 用=表示赋值,用&分隔变量
使用查询字符串同样可以作为参数,不过,不是像使用群组一样,将参数传入到home里面,而是将查询字符串的参数和值以dict的形式保存在request.GET里面,

获取值value的方式有两种:
1.request.GET[key]
2.request.GET.get(key) (建议使用第二种)
views.py

1
2
3
4
def home(request):
# 获取查询字符串内的参数
a = request.GET.get('a')
b = request.GET.get('b')


以关键字参数形式传入额外参数

urls.py

1
url(r'^$', 'app-name.views.home', {'a':5, 'b':3})

views.py

1
2
def home(request, a, b):
return HttpResponse(str(int(a) + int(b)))

注意:在url()中传入的dict的key应该与home的定义的参数一样

以下是错误的写法:

1
url(r'^$', 'app-name.views.home', {'c':5, 'b':3})


群组和关键字参数一起使用

1
url(r'^a=(\d)$b=(\d)', 'app-name.views.home', {'a':5, 'b':3})1

输入 http://localhost:8000/a=6&b=7 浏览器会报错:

1

原因是参数重复赋值了
上述url下, 实现过程如下:
param1 = 6, param2 = 7
a = 5, b = 3
home(request, param1, param2) 还是 home(request, a, b)
浏览器解释器无法判断,所以会报错

使用群组和关键字参数混搭时,要注意不要重复赋值
下面写法都是正确的:

1
url(r'a=(\d)'. 'app-name.views.home', {'b':3})

输入: http://localhost:8000/a=5

注意:如果这么写,又会报错

1
url(r'^b=(\d)$', 'app-name.views.home', {'a':5})1

输入: http://localhost/b=3
报错: 参数a重复赋值

是不是很奇怪:在正则表达式里,不是给a赋值呀,是’b=(\d)’
原因::注意,b=不是说第一个群组的变量名为b,只是让url更容易理解而已,前面说过,群组是按顺序给视图函数传入参数的,所以,不管第一个群组的变量名为什么,都是传给视图函数除了reuqest外的第一个参数,所以,上面实际是给参数a传来两次值,于是报错。

应用案例:

urls.py 相关代码:

1
url(r'^bookdetail/(?P<book_id>\d+)/$', BookDetailView.as_view(), name='bookdetail'),

Views.py代码: 从url中接收book_id

1
2
3
4
5
6
7
class BookDetailView(View):
"""
图书详情
"""
def get(self, request, book_id):
book_detail = Book.objects.get(id=int(book_id))
return render(request, "book_detail.html", {"book_detail": book_detail})

HTML代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<table class="table table-hover">
<thead>
<tr>
<th>No.</th>
<th>书名</th>
<th>作者</th>
<th>出版日期</th>
<th>定价</th>
</tr>
</thead>
<tbody>
{% for book in all_books.object_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td><a href="{% url "bookdetail" book.id %}">{{ book.name }}</a></td>
<td>{{ book.author }}</td>
<td>{{ book.publish_date|date:"Y-m-d" }}</td>
<td>{{ book.price|floatformat:2 }}</td>
</tr>
{% empty %}
<tr>
<td>暂无图书</td>
</tr>
{% endfor %}
</tbody>
</table>

评论系统未开启,无法评论!