一句话,Django中网址是写在 urls.py 文件中,用正则表达式对应 views.py 中的一个函数(或者generic类)。
1、首先我们创建一个新的项目:
django-admin startproduct mysite
如果运行成功,会看到如下目录样式:
mysite
├── manage.py
└── mysite
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
我们会发现执行命令后,新建了一个 mysite 目录,其中还有一个 mysite 目录,这个子目录 mysite 中是一些项目的设置 settings.py 文件,总的urls配置文件 urls.py 以及部署服务器时用到的 wsgi.py 文件, __init__.py 是python包的目录结构必须的,与调用有关。
2、新建一个app,叫做learn
python manage.py startapp learn # learn 是一个app的名称
我们可以看到mysite中多个一个 learn 文件夹,其中有以下文件。
learn/
├── __init__.py
├── admin.py
├── models.py
├── tests.py
└── views.py
然后将app添加到工程的setting.py文件的
INSTALL_APPS。
如果不添加的话, 新建的 app 如果不加到 INSTALL_APPS 中的话, django 就不能自动找到app中的模板文件(app-name/templates/下的文件)和静态文件(app-name/static/中的文件)
或者直接用Pycharm创建一个Django工程和app,Pycharm会自动为我们完成添加。
3、定义视图函数(访问页面时的内容)
我们在learn这个目录中,把views.py打开,修改其中的源代码,改成下面的
1
2
3
4
5
|
#coding:utf-8
from
django.http
import
HttpResponse
def
index(request):
return
HttpResponse(u
"欢迎光临 自强学堂!"
)
|
第一行是声明编码为utf-8, 因为我们在代码中用到了中文,如果不声明就报错.
第二行引入HttpResponse,它是用来向网页返回内容的,就像Python中的 print 一样,只不过 HttpResponse 是把内容显示到网页上。
我们定义了一个index()函数,第一个参数必须是 request,与网页发来的请求有关,request 变量里面包含get或post的内容,用户浏览器,系统等信息在里面(后面会讲,先了解一下就可以)。
函数返回了一个 HttpResponse 对象,可以经过一些处理,最终显示几个字到网页上。
那问题来了,我们访问什么网址才能看到刚才写的这个函数呢?怎么让网址和函数关联起来呢?
定义视图函数相关的URL(网址) (即规定 访问什么网址对应什么内容)
我们打开 mysite/mysite/urls.py 这个文件, 修改其中的代码:
由于 Django 版本对 urls.py 进行了一些更改:
Django 1.7.x 及以下的同学可能看到的是这样的:
1
2
3
4
5
6
7
8
9
10
11
|
from
django.conf.urls
import
patterns, include, url
from
django.contrib
import
admin
admin.autodiscover()
urlpatterns
=
patterns('',
url(r
'^$'
,
'learn.views.index'
),
# new
# url(r'^blog/', include('blog.urls')),
url(r
'^admin/'
, include(admin.site.urls)),
)
|
Django 1.8.x及以上,Django 官方鼓励(或说要求)先引入,再使用:
1
2
3
4
5
6
7
8
|
from
django.conf.urls
import
url
from
django.contrib
import
admin
from
learn
import
views as learn_views
# new
urlpatterns
=
[
url(r
'^$'
, learn_views.index),
# new
url(r
'^admin/'
, admin.site.urls),
]
|
以上都修改并保存后,我们来看一下效果!
在终端上运行 python manage.py runserver 我们会看到类似下面的信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
$ python manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
You have unapplied migrations; your app may not work properly until they are applied.
Run 'python manage.py migrate' to apply them.
December 22, 2015 - 11:57:33
Django version 1.9, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
|
我们打开浏览器,访问 http://127.0.0.1:8000/
不出意料的话会看到:
注意:如果是在另一台电脑上访问要用 python manage.py ip:port 的形式,比如监听所有ip:
1
2
3
|
python manage.py runserver 0.0.0.0:8000
监听机器上所有ip 8000端口,访问时用电脑的ip代替 127.0.0.1
|
4. 采用 /add/?a=4&b=5 这样GET方法进行
1
2
3
|
django-admin.py startproject zqxt_views
cd
zqxt_views
python manage.py startapp calc
|
自动生成目录大致如下(因不同的 Django 版本有一些差异,如果差异与这篇文章相关,我会主动提出来,没有说的,暂时可以忽略他们之间的差异,后面的教程也是这样做):
1
2
3
4
5
6
7
8
9
10
11
12
13
|
zqxt_views/
├── calc
│ ├── __init__.py
│ ├── admin.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── manage.py
└── zqxt_views
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
|
我们修改一下 calc/views.py文件
1
2
3
4
5
6
7
8
|
from
django.shortcuts
import
render
from
django.http
import
HttpResponse
def
add(request):
a
=
request.GET[
'a'
]
b
=
request.GET[
'b'
]
c
=
int
(a)
+
int
(b)
return
HttpResponse(
str
(c))
|
注:request.GET 类似于一个字典,更好的办法是用 request.GET.get('a', 0) 当没有传递 a 的时候默认 a 为 0
接着修改 zqxt_views/urls.py 文件,添加一个网址来对应我们刚才新建的视图函数。
Django 1.7.x 及以下的同学可能看到的是这样的:
1
2
3
4
5
6
7
8
9
10
11
12
|
from
django.conf.urls
import
patterns, include, url
from
django.contrib
import
admin
admin.autodiscover()
urlpatterns
=
patterns('',
# Examples:
url(r
'^add/$'
,
'calc.views.add'
, name
=
'add'
),
# 注意修改了这一行
# url(r'^blog/', include('blog.urls')),
url(r
'^admin/'
, include(admin.site.urls)),
)
|
Django 1.8.x及以上,Django 官方鼓励(或说要求)先引入,再使用。
1
2
3
4
5
6
7
8
9
|
from
django.conf.urls
import
url
from
django.contrib
import
admin
from
calc
import
views as calc_views
urlpatterns
=
[
url(r
'^add/$'
, calc_views.add, name
=
'add'
),
# 注意修改了这一行
url(r
'^admin/'
, admin.site.urls),
]
|
注意:低版本的 Django 也可以先引入,再使用
我们打开开发服务器并访问
1
2
3
|
python manage.py runserver
如果提示 Error: That port is already
in
use.在后面加上端口号8001,8888等
python manage.py runserver 8001
|
打开网址:http://127.0.0.1:8000/add/ 就可以看到
MultiValueDictKeyError at /add/
这是因为我们并没有传值进去,我们在后面加上 ?a=4&b=5,即访问 http://127.0.0.1:8000/add/?a=4&b=5
就可以看到网页上显示一个 9,试着改变一下a和b对应的值试试看?
5. 采用 /add/3/4/ 这样的网址的方式
前面介绍的时候就说过 Django 支持优雅的网址
我们接着修改 calc/views.py文件,再新定义一个add2 函数,原有部分不再贴出
1
2
3
|
def
add2(request, a, b):
c
=
int
(a)
+
int
(b)
return
HttpResponse(
str
(c))
|
接着修改 zqxt_views/urls.py 文件,再添加一个新的 url
Django 1.7.x 及以下:
1
|
url(r
'^add/(\d+)/(\d+)/$'
,
'calc.views.add2'
, name
=
'add2'
),
|
Django 1.8.x 及以上:
1
|
url(r
'^add/(\d+)/(\d+)/$'
, calc_views.add2, name
=
'add2'
),
|
我们可以看到网址中多了 (\d+), 正则表达式中 \d 代表一个数字,+ 代表一个或多个前面的字符,写在一起 \d+ 就是一个或多个数字,用括号括起来的意思是保存为一个子组(更多知识请参见 Python 正则表达式),每一个子组将作为一个参数,被 views.py 中的对应视图函数接收。
我们再访问 http://127.0.0.1:8000/add/4/5/ 就可以看到和刚才同样的效果,但是这回网址更优雅了