阅读目录
python Django教程 之 安装、基本命令、视图与网站
一、简介
Django 中提供了开发网站经常用到的模块,常见的代码都为你写好了,通过减少重复的代码,Django 使你能够专注于 web 应用上有 趣的关键性的东西。为了达到这个目标,Django 提供了通用Web开发模式的高度抽象,提供了频繁进行的编程作业的快速解决方法,以及为“如何解决问题”提供了清晰明了的约定。Django的理念是DRY(Don't Repeat Yourself)来鼓励快速开发!
让我们一览 Django 全貌
urls.py
网址入口,关联到对应的views.py中的一个函数(或者generic类),访问网址就对应一个函数。
views.py
处理用户发出的请求,从urls.py中对应过来, 通过渲染templates中的网页可以将显示内容,比如登陆后的用户名,用户请求的数据,输出到网页。
models.py
与数据库操作相关,存入或读取数据时用到这个,当然用不到数据库的时候 你可以不使用。
forms.py
表单,用户在浏览器上输入数据提交,对数据的验证工作以及输入框的生成等工作,当然你也可以不使用。
templates 文件夹
views.py 中的函数渲染templates中的Html模板,得到动态内容的网页,当然可以用缓存来提高速度。
admin.py
后台,可以用很少量的代码就拥有一个强大的后台。
settings.py
Django 的设置,配置文件,比如 DEBUG 的开关,静态文件的位置等。
二、安装
在安装Django之前,系统上必须已经安装了Python,至于如何安装Python,这里就不多讲了
安装好Python之后,建议安装easy_install,这样直接使用命令easy_install django即可下载最新版本,非常方便。
注意:以下方法中任何一种方法安装都可,不用每个都试一次。
另外 建议自行安装 bpython,这样在用起来会爽很多。进入终端的时候输入 bpython 可以有提示。当然也可以选择用 ipython
一. 用 pip 来安装
2.1 需要先安装pip
(1). ubuntu:
sudo apt-get install python-pip
(2). RedHat
yum install python-pip
(3). Linux, Mac OSX, Windows 下都可用 get-pip.py 来安装 pip:https://pip.pypa.io/en/latest/installing.html
或者直接下载:get-pip.py 然后运行在终端运行 python get-pip.py 就可以安装 pip。
Note: 也可以下载 pip 源码包,运行 python setup.py install 进行安装
2.2 利用 pip 安装 Django
(sudo) pip install Django 或者 (sudo) pip install Django==1.6.10 或者 pip install Django==1.7.6
如果想升级 pip 可以用:
(sudo) pip install --upgrade pip
Windows 用户不要加 sudo,如果提示 ‘python’不是内部或外部命令,也不是可运行的程序或批处理文件。
那说明你的 Python 没有安装好,或者环境变量没有配置正确,最简单的办法是安装新版本的 Python 2.7.9, 里面集成了 pip,安装时要勾选上环境变量这一个
二. 下载源码安装
https://www.djangoproject.com/download/
如果是源码包, 比如 django-1.7.6.tar.gz
3.1 Linux 或 Mac 下
tar -xvzf django-1.7.6.tar.gz
cd django-1.7.6
(sudo) python setup.py install
3.2 Windows 下
直接用解压软件解压,然后到命令行(XP/Win7点击开始,在下面的那个输入框中输入 cmd, Win8在开始那里点右键,选择命令行)
比如在 D:\django-1.7.6\ 这个文件夹下
cd D:
cd django-1.7.6
python setup.py install
什么?提示 ‘python’不是内部或外部命令,也不是可运行的程序或批处理文件。
那说明你的 Python 没有安装好,或者路径没有配置正确
Linux用自带源进行安装
1.1 ubuntu 下安装 Django
sudo apt-get install python-django -y
1.2 redhat 下安装用 yum
yum install python-django
注意:自带源安装的 Django 一般版本比较旧,而用 pip 可以安装最新的版本。
2. 检查是否安装成功
终端上输入 python ,点击 Enter,进行 python 环境
1 >>> import django
2 >>> django.VERSION
3 (1, 7, 6, 'final', 0)
4 >>>
5 >>> django.get_version()
6 '1.7.6'
如果运行后看到版本号,就证明安装成功了!
3. 扩展:搭建多个互不干扰的开发环境
我们有的时候会发现,一个电脑上有多个项目,一个依赖 Django 1.8,另一个比较旧的项目又要用 Django 1.5,这时候怎么办呢?
我们需要一个依赖包管理的工具来处理不同的环境。
如果不想搭建这个环境,只想用某一个版本的 Django 也可以,但是推荐学习此内容!
3.1 环境搭建
开发会用 virtualenv 来管理多个开发环境,virtualenvwrapper 使得virtualenv变得更好用
# 安装:
(sudo) pip install virtualenv virtualenvwrapper
Linux/Mac OSX 下:
修改~/.bash_profile或其它环境变量相关文件(如 .bashrc 或用 ZSH 之后的 .zshrc),添加以下语句
export WORKON_HOME=$HOME/.virtualenvs
export PROJECT_HOME=$HOME/workspace
source /usr/local/bin/virtualenvwrapper.sh
修改后使之立即生效(也可以重启终端使之生效):
source ~/.bash_profile
Windows 下:
pip install virtualenvwrapper-win
可选】Windows下默认虚拟环境是放在用户名下面的Envs中的,与桌面,我的文档,下载等文件夹在一块的。更改方法:计算机,属性,高级系统设置,环境变量,添加WORKON_HOME,如图(windows 10 环境变量设置截图):
3.2 使用方法:
mkvirtualenv zqxt:创建运行环境zqxt
workon zqxt: 工作在 zqxt 环境 或 从其它环境切换到 zqxt 环境
deactivate: 退出终端环境
其它的:
rmvirtualenv ENV:删除运行环境ENV
mkproject mic:创建mic项目和运行环境mic
mktmpenv:创建临时运行环境
lsvirtualenv: 列出可用的运行环境
lssitepackages: 列出当前环境安装了的包
创建的环境是独立的,互不干扰,无需sudo权限即可使用 pip 来进行包的管理。
三、Django 基本命令
1. 新建一个 django project
django-admin startproject project-name
一个 project 为一个项目,project-name 项目名称,改成你自己的,要符合Python 的变量命名规则(以下划线或字母开头)
2. 新建 app
python manage.py startapp app-name
或 django-admin.py startapp app-name
一般一个项目有多个app, 当然通用的app也可以在多个项目中使用。
3. 同步数据库
python manage.py syncdb
注意:Django 1.7.1及以上的版本需要用以下命令
python manage.py makemigrations
python manage.py migrate
这种方法可以创建表,当你在models.py中新增了类时,运行它就可以自动在数据库中创建表了,不用手动创建。
备注:对已有的 models 进行修改,Django 1.7之前的版本的Django都是无法自动更改表结构的,不过有第三方工具 south,详见 Django 数据库迁移 一节。
4. 使用开发服务器
开发服务器,即开发时使用,一般修改代码后会自动重启,方便调试和开发,但是由于性能问题,建议只用来测试,不要用在生产环境。
python manage.py runserver # 当提示端口被占用的时候,可以用其它端口: python manage.py runserver 8001 python manage.py runserver 9999 (当然也可以kill掉占用端口的进程) # 监听所有可用 ip (电脑可能有一个或多个内网ip,一个或多个外网ip,即有多个ip地址) python manage.py runserver 0.0.0.0:8000 # 如果是外网或者局域网电脑上可以用其它电脑查看开发服务器 # 访问对应的 ip加端口,比如 http://172.16.20.2:8000
5. 清空数据库
python manage.py flush
此命令会询问是 yes 还是 no, 选择 yes 会把数据全部清空掉,只留下空表。
6. 创建超级管理员
python manage.py createsuperuser
# 按照提示输入用户名和对应的密码就好了邮箱可以留空,用户名和密码必填
# 修改 用户密码可以用:
python manage.py changepassword username
7. 导出数据 导入数据
python manage.py dumpdata appname > appname.json
python manage.py loaddata appname.json
关于数据操作 详见后面数据导入和数据迁移内容,现在了解有这个用法就可以了。
8. Django 项目环境终端
python manage.py shell
如果你安装了 bpython 或 ipython 会自动用它们的界面,推荐安装 bpython。
这个命令和 直接运行 python 或 bpython 进入 shell 的区别是:你可以在这个 shell 里面调用当前项目的 models.py 中的 API,对于操作数据,还有一些小测试非常方便。
9. 数据库命令行
python manage.py dbshell
Django 会自动进入在settings.py中设置的数据库,如果是 MySQL 或 postgreSQL,会要求输入数据库用户密码。
在这个终端可以执行数据库的SQL语句。如果您对SQL比较熟悉,可能喜欢这种方式。
10. 更多命令
终端上输入 python manage.py 可以看到详细的列表,在忘记子名称的时候特别有用。
四、Django 视图与网址
4.1 首先,新建一个项目(project), 名称为 mysite
django-admin startproject mysite
备注:
1. 如果 django-admin 不行,请用 django-admin.py
2. 如果是在Linux是用源码安装的,或者用 pip 安装的,也是用 django-admin.py 命令
运行后,如果成功的话, 我们会看到如下的目录样式
1 mysite 2 ├── manage.py 3 └── mysite 4 ├── __init__.py 5 ├── settings.py 6 ├── urls.py 7 └── wsgi.py
我们会发现执行命令后,新建了一个 mysite 目录,其中还有一个 mysite 目录,这个子目录 mysite 中是一些项目的设置settings.py 文件,总的urls配置文件 urls.py 以及部署服务器时用到的 wsgi.py 文件, __init__.py 是python包的目录结构必须的,与调用有关。
我们到外层那个 mysite 目录下(不是mysite中的mysite目录)
4.2新建一个应用(app), 名称叫 learn
python manage.py startapp learn # learn 是一个app的名称
我们可以看到mysite中多个一个 learn 文件夹,其中有以下文件。
1 learn/
2 ├── __init__.py
3 ├── admin.py
4 ├── models.py
5 ├── tests.py
6 └── views.py
注:Django 1.8.x 以上的,还有一个 migrations 文件夹。Django 1.9.x 还会在 Django 1.8 的基础上多出一个 apps.py 文件。但是这些都与本文无关。
把我们新定义的app加到settings.py中的INSTALL_APPS中
修改 mysite/mysite/settings.py
INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'learn', )
备注,这一步是干什么呢? 新建的 app 如果不加到 INSTALL_APPS 中的话, django 就不能自动找到app中的模板文件(app-name/templates/下的文件)和静态文件(app-name/static/中的文件) , 后面你会学习到它们分别用来干什么.
定义视图函数(访问页面时的内容)
我们在learn这个目录中,把views.py打开,修改其中的源代码,改成下面的
#coding:utf-8
from django.http import HttpResponse
def index(request):
return HttpResponse(u"Hello World!")
第一行是声明编码为utf-8, 因为我们在代码中用到了中文,如果不声明就报错.
第二行引入HttpResponse,它是用来向网页返回内容的,就像Python中的 print 一样,只不过 HttpResponse 是把内容显示到网页上。
我们定义了一个index()函数,第一个参数必须是 request,与网页发来的请求有关,request 变量里面包含get或post的内容,用户浏览器,系统等信息在里面(后面会讲,先了解一下就可以)。
函数返回了一个 HttpResponse 对象,可以经过一些处理,最终显示几个字到网页上。
那问题来了,我们访问什么网址才能看到刚才写的这个函数呢?怎么让网址和函数关联起来呢?
定义视图函数相关的URL(网址) (即规定 访问什么网址对应什么内容)
我们打开 mysite/mysite/urls.py 这个文件, 修改其中的代码:
注:由于 Django 版本对 urls.py 进行了一些更改
Django 1.7.x 及以下的同学可能看到的是这样的:
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 官方鼓励(或说要求)先引入,再使用:
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 我们会看到类似下面的信息:
$ 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:
python manage.py runserver 0.0.0.0:8000
监听机器上所有ip 8000端口,访问时用电脑的ip代替 127.0.0.1
Django中的 urls.py 用的是正则进行匹配的,如果不熟悉,您可以学习正则表达式以及Python正则表达式。
五、Django 视图与网址进阶
5.1在网页上做加减法
5.1.1 采用 /add/?a=4&b=5 这样GET方法进行
django-admin.py startproject zqxt_views
cd zqxt_views
python manage.py startapp calc
自动生成目录大致如下(因不同的 Django 版本有一些差异,如果差异与这篇文章相关,我会主动提出来,没有说的,暂时可以忽略他们之间的差异,后面的教程也是这样做):
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文件
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 及以下的同学可能看到的是这样的:
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 官方鼓励(或说要求)先引入,再使用,低版本的 Django 也可以这样用:
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), ]
我们打开开发服务器并访问
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/ 就可以看到
这是因为我们并没有传值进去,我们在后面加上 ?a=4&b=5,即访问 http://127.0.0.1:8000/add/?a=4&b=5
就可以看到网页上显示一个 9,试着改变一下a和b对应的值试试看?
5.1.2 采用 /add/3/4/ 这样的网址的方式
前面介绍的时候就说过 Django 支持优雅的网址
我们接着修改 calc/views.py文件,再新定义一个add2 函数,原有部分不再贴出
def add2(request, a, b):
c = int(a) + int(b)
return HttpResponse(str(c))
接着修改 zqxt_views/urls.py 文件,再添加一个新的 url
Django 1.7.x 及以下:
url(r'^add/(\d+)/(\d+)/$', 'calc.views.add2', name='add2'),
Django 1.8.x 及以上:
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/ 就可以看到和刚才同样的效果,但是这回网址更优雅了
5.2 url 中的 name [技能提升]
我们还有刚才的代码,再来看一下 urls.py 中的代码(注意:第二条改成了 add2)
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'^add2/(\d+)/(\d+)/$', calc_views.add2, name='add2'), url(r'^admin/', admin.site.urls), ]
url(r'^add/$', calc_views.add, name='add'), 这里的 name='add' 是用来干什么的呢?
我们在开发的时候,刚开始想用的是 /add2/4/5/ ,后来需求发生变化,比如我们又想改成 /4_add_5/这样的格式,但是我们在网页中,代码中很多地方都写死的是
<a href="/add2/4/5/">计算 4+5</a>
那么有没有更优雅的方式来解决这个问题呢?当然答案是肯定的。
我们先说一下如何用 Python 代码获取对应的网址:
我们在终端上输入(推荐安装 bpython, 这样Django会用 bpython的 shell)
C:\Users\Administrator\Desktop\文档\day17\zqxt_views>python3.5 manage.py shell
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:38:48) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.core.urlresolvers import reverse
>>> reverse('add2', args=(4,5))
'/add/4/5/'
>>> reverse('add2', args=(444,555))
'/add/444/555/'
>>>
reverse 接收 url 中的 name 作为第一个参数,我们在代码中就可以通过 reverse() 来获取对应的网址(这个网址可以用来跳转,也可以用来计算相关页面的地址),只要对应的 url 的name不改,就不用改代码中的网址。
在网页模板中也是一样,可以很方便的使用。
不带参数的: {% url 'name' %} 带参数的:参数可以是变量名 {% url 'name' 参数 %} 例如: <a href="{% url 'add2' 4 5 %}">link</a>
上面的代码渲染成最终的页面是
<a href="/add2/4/5/">link</a>
这样就可以通过 {% url 'add2' 4 5 %} 获取到对应的网址 /add2/4/5/
当 urls.py 进行更改,前提是不改 name(这个参数设定好后不要轻易改),获取的网址也会动态地跟着变,比如改成:
url(r'^new_add/(\d+)/(\d+)/$', 'calc.views.add2', name='add2'),
注意看重点 add2 变成了 new_add,但是后面的 name='add2' 没改,这时 {% url 'add2' 4 5 %} 就会渲染对应的网址成 /new_add/4/5/
reverse 函数也是一样,获取的时候会跟着变成新的网址,这样,在想改网址时只需要改 urls.py 中的正则表达式(url 参数第一部分),其它地方都“自动”跟着变了,是不是这样更好呢?
另外,如何让以前的 /add2/3/4/自动跳转到新的网址呢?要知道Django不会帮你做这个,这个需要自己来写一个跳转方法:
具体思路是,在 views.py 写一个跳转的函数:
from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse def old_add2_redirect(request, a, b): return HttpResponseRedirect( reverse('add2', args=(a, b)) )
urls.py中:
url(r'^add2/(\d+)/(\d+)/$', calc_views.old_add2_redirect),
url(r'^new_add/(\d+)/(\d+)/$', calc_views.add2, name='add2'),
这样,假如用户收藏夹中有 /add2/4/5/ ,访问时就会自动跳转到新的 /new_add/4/5/ 了
开始可能觉得直接写网址简单,但是用多了你一定会发现,用“死网址”的方法很糟糕