django + bootstrap 使用网页模板

项目需要,快速上手 Django 的笔记。

初识 Django

Django 使用了类似 MVC 的架构,只是在定义和解释上略为不同,称为 MTV ( Model–Template–View )。
process.jpg

Django 处理 request 的流程:

  • 浏览器送出 HTTP request
  • Django 依据 URL configuration 分配至对应的 View
  • View 进行资料库的操作或其他运算,并回传 HttpResponse
  • 浏览器依据 HTTP response 显示网页画面

另外 Django 无需数据库就可以使用,它提供了对象关系映射器(ORM),可以使用 Python 代码来描述数据库结构。

Install

1
$ pip install django

查看版本

1
2
$ python -m django --version
1.10.5

Simple Example

Start project

1
$ django-admin startproject mysite

目录结构:

1
2
3
4
5
6
7
mysite/
├── manage.py
└── mysite
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py

各个文件的作用:

1
2
3
4
5
6
7
8
9
10
11
12
The outer mysite/ root directory is just a container for your project. Its name doesn’t matter to Django; you can rename it to anything you like.
manage.py: A command-line utility that lets you interact with this Django project in various ways. You can read all the details about manage.py in django-admin and manage.py.
The inner mysite/ directory is the actual Python package for your project. Its name is the Python package name you’ll need to use to import anything inside it (e.g. mysite.urls).
mysite/__init__.py: An empty file that tells Python that this directory should be considered a Python package. If you’re a Python beginner, read more about packages in the official Python docs.
mysite/settings.py: Settings/configuration for this Django project. Django settings will tell you all about how settings work.
mysite/urls.py: The URL declarations for this Django project; a “table of contents” of your Django-powered site. You can read more about URLs in URL dispatcher.
mysite/wsgi.py: An entry-point for WSGI-compatible web servers to serve your project. See How to deploy with WSGI for more details.

现在就可以在 mysite 目录下运行了

1
$ python manage.py runserver

浏览器打开 ‘http://127.0.0.1:8000/‘ 能看到 “Welcome to Django” 的页面。

如果有别的程序占用端口,可以修改 django 运行的端口

1
$ python manage.py runserver 8080

修改 server 的 IP

1
$ python manage.py runserver 0.0.0.0:8000

修改 python 代码并保存时会自动加载 server,不用重新启动。然而,如果有添加文件等操作,就要重新启动了。

Create app

1
$ python manage.py startapp mysample

目录结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mysite/
├── manage.py
├── mysample
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
└── mysite
├── __init__.py
├── __pycache__
│   ├── __init__.cpython-36.pyc
│   └── settings.cpython-36.pyc
├── settings.py
├── urls.py
└── wsgi.py

Projects vs apps
所谓 app 是指完成一些功能的 web 应用,比如博客系统(weblog system),公共记录的数据库(a database of public records)或者是一个简单的投票系统(a simple poll app)。project 是指一个特定网站的一系列配置文件和应用的集合。一个项目(project)可以包含多个应用(app),一个应用(app)可以被多个项目(project)使用。

Views

Django view 其实是一个 function,处理 HttpRequest,并回传 HttpResponse

  • 收到 HttpRequest 参数
    Django 从网页接收到 request 后,会将 request 中的信息封装产生一个 HttpRequest,并当成第一个参数,传入对应的 view function
  • 需要回传 HttpResponse
    HttpResponse.content
    HttpResponse.status_code …等

编辑 mysample/views.py:

1
2
3
4
5
6
7
from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader
# Create your views here.
def index(request):
return HttpResponse("Hello, world.")

这段代码做的是:

  • 从 django.http 中引用 HttpResponse 类别
  • 宣告 hello_world 这个 view
  • 当 hello_world 被呼叫时,回传包含字串 Hello World! 的 HttpResponse

URL

Django 需要知道 URL 与 view 的对应关系,这个对应关系就是 URL conf (URL configuration),通常定义在 urls.py,包含了一连串的规则 (URL patterns),Django 收到 request 时,会一一比对 URL conf 中的规则,决定要执行哪个 view function

在 mysample 里新建一个 urls.py 文件来 map url,现在的目录结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mysite/
├── manage.py
├── mysample
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
└── mysite
├── __init__.py
├── __pycache__
│   ├── __init__.cpython-36.pyc
│   └── settings.cpython-36.pyc
├── settings.py
├── urls.py
└── wsgi.py

编辑 mysample/urls.py:

1
2
3
4
5
6
7
8
9
from django.conf.urls import url
from . import views
app_name = 'mysample'
urlpatterns = [
# ex: /mysample/
url(r'^$', views.index, name='index'),
]

现在要把这个 urls.py 连到 mysite 上,编辑 mysite/urls.py:

1
2
3
4
5
6
7
8
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
# point the root URLconf at the mysample.urls module
url(r'^mysample/', include('mysample.urls')),
url(r'^admin/', admin.site.urls),
]

url() 函数接收四个参数,两个是必需的: regex 和 view,还有两个是可选的:kwargs 和 name。

  • regex – 定义的 URL 规则
    - 规则以 regular expression(正规表示式)来表达
    - r'^mysample/' 代表的是 mysample/ 这种 URL
    - Django 从第一个开始,按顺序依次使用列表里的正则表达式来尝试匹配请求的 URL,直到遇到一个可以匹配的表达式
    - 不尝试匹配 GET 或 POST 的参数,也不匹配域名部分
    
  • view – 对应的 view function
    - 当 Django 找到匹配的正则表达式时,就会调用这个视图函数
    - 调用时传递的第一个参数是一个 HttpRequest 对象,后续的参数是所有被正则表达数捕捉的部分
    - 如果正则式使用简单捕获,捕获结果会作为位置参数传递;如果使用名字捕获,捕获结果会作为关键字参数传递
    
  • url() 参数之 kwargs
    - 任意个关键字参数可以作为一个字典传递给目标视图函数
    
  • url() 参数之 name
    - 给 URL 起个名字,以便在 Django 的模板里无二义性的引用到它
    - 这个非常有用的特性允许你只用更改一个文件就能全局性的改变某个 URL
    

我们使用的 include() 函数只是简单的引用其他的 URLconf 文件,让 URLconf 也能轻松的「即插即用」。请注意 include() 函数的正则表达式不包含 $ 符号(匹配字符串结尾)但是结尾有斜线。当 Django 遇到一个 include(),它砍掉被正则表达式匹配上的部分,并把剩余的字符串发送个作为参数的 URLconf 做进一步处理。

然后运行:

1
$ python manage.py runserver

打开 ‘http://localhost:8000/mysample/',就可以看到 “Hello, world.” 主页。

Bootstrap

这里使用的模板是SB Admin

static 和 templates 文件

在 mysite 下新建文件夹 static,把 bootstrap 下载的模板复制到里面,然后在 mysite/mysite 下新建一个 templates 文件夹,把 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
└── mysite
├── manage.py
├── mysample
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   ├── urls.cpython-36.pyc
│   │   └── views.cpython-36.pyc
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── mysite
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   ├── settings.cpython-36.pyc
│   │   ├── urls.cpython-36.pyc
│   │   └── wsgi.cpython-36.pyc
│   ├── settings.py
│   ├── templates
│   │   └── mysample
│   │   └── dashboard.html
│   ├── urls.py
│   └── wsgi.py
└── static
├── css
│   ├── bootstrap-rtl.css
│   ├── bootstrap-rtl.min.css
│   ├── bootstrap.css
│   ├── bootstrap.min.css
│   ├── plugins
│   │   └── morris.css
│   ├── sb-admin-rtl.css
│   └── sb-admin.css
├── font-awesome
│   ├── css
│   │   ├── font-awesome.css
│   │   └── font-awesome.min.css
│   ├── fonts
│   │   ├── FontAwesome.otf
│   │   ├── fontawesome-webfont.eot
│   │   ├── fontawesome-webfont.svg
│   │   ├── fontawesome-webfont.ttf
│   │   └── fontawesome-webfont.woff
│   ├── less
│   │   ├── bordered-pulled.less
│   │   ├── core.less
│   │   ├── fixed-width.less
│   │   ├── font-awesome.less
│   │   ├── icons.less
│   │   ├── larger.less
│   │   ├── list.less
│   │   ├── mixins.less
│   │   ├── path.less
│   │   ├── rotated-flipped.less
│   │   ├── spinning.less
│   │   ├── stacked.less
│   │   └── variables.less
│   └── scss
│   ├── _bordered-pulled.scss
│   ├── _core.scss
│   ├── _fixed-width.scss
│   ├── _icons.scss
│   ├── _larger.scss
│   ├── _list.scss
│   ├── _mixins.scss
│   ├── _path.scss
│   ├── _rotated-flipped.scss
│   ├── _spinning.scss
│   ├── _stacked.scss
│   ├── _variables.scss
│   └── font-awesome.scss
├── fonts
│   ├── glyphicons-halflings-regular.eot
│   ├── glyphicons-halflings-regular.svg
│   ├── glyphicons-halflings-regular.ttf
│   ├── glyphicons-halflings-regular.woff
│   └── glyphicons-halflings-regular.woff2
└── js
├── bootstrap.js
├── bootstrap.min.js
├── jquery.js
└── plugins
├── flot
│   ├── excanvas.min.js
│   ├── flot-data.js
│   ├── jquery.flot.js
│   ├── jqu
ery.flot.pie.js
│   ├── jquery.flot.resize.js
│   └── jquery.flot.tooltip.min.js
└── morris
├── morris-data.js
├── morris.js
├── morris.min.js
└── raphael.min.js

注意要修改 html 里引用 css 和 js 的路径,如:

1
<link href="/static/css/bootstrap.min.css" rel="stylesheet">

配置

修改 mysite 下的 settings.py,添加 templates 的目录路径以及 static files 的目录路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['your directory/mysite/mysite/templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = (
'your directory/mysite/static/',
)

渲染

修改 mysample/views.py,渲染 html 文件而不是仅仅输出一段文字

1
2
3
4
5
6
7
from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader
# Create your views here.
def index(request):
return render_to_response('index.html')

效果图

pic.jpg

参考链接
Django简易教程之一(models)
Django document
Django-intro 中文版

徐阿衡 wechat
欢迎关注:徐阿衡的微信公众号
客官,打个赏呗~