python  Django教程  之 安装、基本命令、视图与网站

一、简介

Django 中提供了开发网站经常用到的模块,常见的代码都为你写好了,通过减少重复的代码,Django 使你能够专注于 web 应用上有 趣的关键性的东西。为了达到这个目标,Django 提供了通用Web开发模式的高度抽象,提供了频繁进行的编程作业的快速解决方法,以及为“如何解决问题”提供了清晰明了的约定。Django的理念是DRY(Don't Repeat Yourself)来鼓励快速开发!

 

让我们一览 Django 全貌

网址入口,关联到对应的views.py中的一个函数(或者generic类),访问网址就对应一个函数。

处理用户发出的请求,从urls.py中对应过来, 通过渲染templates中的网页可以将显示内容,比如登陆后的用户名,用户请求的数据,输出到网页。

与数据库操作相关,存入或读取数据时用到这个,当然用不到数据库的时候 你可以不使用。

表单,用户在浏览器上输入数据提交,对数据的验证工作以及输入框的生成等工作,当然你也可以不使用。

templates 文件夹

views.py 中的函数渲染templates中的Html模板,得到动态内容的网页,当然可以用缓存来提高速度。

后台,可以用很少量的代码就拥有一个强大的后台。

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,安装时要勾选上环境变量这一个

 

二. 下载源码安装

如果是源码包, 比如 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 变量里面包含getpost的内容,用户浏览器,系统等信息在里面(后面会讲,先了解一下就可以)。

函数返回了一个 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/ 就可以看到

这是因为我们并没有传值进去,我们在后面加上 

就可以看到网页上显示一个 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/ 了

开始可能觉得直接写网址简单,但是用多了你一定会发现,用“死网址”的方法很糟糕