Django介绍
参考文档:
Django官方文档 官方文档中文翻译
Django是一个开放源代码的Web应用框架,由Python写成,基于MVC构造。但是在Django中,控制器接受用户输入的部分由框架自行处理,
所以Django里更关注的是模型(Model)、模板(Template)和视图(Views),称为MTV模式。一个Django应用程序的基本目录结构如下:
project_name/
project_name/
__init__.py
settings.py
urls.py
*views.py
wsgi.py
manage.py
*static/
base/
css/
bootstrap.min.css
js/
bootstrap.min.js
*templates/
index.html
base.html
app_name/
show.html
*app_name/
__init__.py
admin.py
urls.py
views.py
models.py
forms.py
tests.py
模型(Model),即数据存取层———处理与数据相关的所有事务:如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等.
模板(Template),即表现层 ———处理与表现相关的决定:如何在页面或者其他类型文档中进行显示.
视图(View),即业务逻辑层 ———存取模型及调取恰当模板的相关逻辑,模型与模板之间的桥梁.
Django 如何处理一个请求
当一个用户请求Django站点的一个页面,下面是Django系统决定执行哪个Python代码使用的算法:
- Django决定要使用的根URLconf模块。通常,这个值就是ROOT_URLCONF的设置.
- Django加载该Python模块并寻找可用的urlpatterns它是django.conf.urls.url()实例的一个Python列表。
- Django依次匹配每个URL模式,在与请求的URL匹配的第一个模式停下来。
- 一旦其中的一个正则表达式匹配上,Django将导入并调用给出的视图,它是一个简单的Python函数(或者一个基于类的视图)。视图将获得如下参数:
- 一个HttpRequest 实例。
- 如果匹配的正则表达式没有返回命名的组,那么正则表达式匹配的内容将作为位置参数提供给视图。
- 关键字参数由正则表达式匹配的命名组组成,但是可以被django.conf.urls.url()的可选参数kwargs覆盖。
如果视图返回时调用了模板,调用templates
下面的html进行渲染展示。
- 如果没有匹配到正则表达式,或者如果过程中抛出一个异常,Django将调用一个适当的错误处理视图。
快速搭建一个网站
安装Python和Django
Python 2.7.*版本,Django 1.8.3版本,由于系统的不同,安装过程稍有不同。
网站搭建
新建一个工程
1 | django-admin startproject mysite |
目录结构如上面所示,然后我们在mysite下面新建一个views.py
视图文件,在视图文件中定义我们的视图.mysite/views.py
1
from django.shortcuts import render
def index(request):
return render(request, 'index.html')
在templates
目录下面新建index.html
文件.templates/index.html
1
<html>
<head><title>My First Website!</title></head>
<body><p>Hello World!</p></body>
</html>
需要在settings.py
中设置模板的路径.mysite/settings.py
1
TEMPLATES = [
{
'DIRS': [os.path.join(BASE_DIR, 'templates')],
},
]
在urls.py
中配置URL访问规则.mysite/urls.py
1
from django.conf.urls import patterns, url
from . import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
)
启动本地Django服务器运行我们的网站程序.1
python manage.py runserver 8000
在浏览器中打开localhost:8000
会看到我们的欢迎页面.
在工程下面添加一个应用
一个网站可能分为不同的模块,每个模块来实现不同的功能,对于每一个模块我们类比于Django中的APP,每一个APP用来实现不同的功能,使框架低耦合。
新建一个应用:1
python manage.py startapp app_name
然后在project_name/settings.py中包含这个应用.settings.py
INSTALLED_APPS = (
...,
'app_name',
)
运行python manage.py startapp sample
新建一个名为sample的应用,来展示我们的例子.
URL调度器
官方文档 中文 英文
简洁、优雅的URL模式在高质量的Web应用中是非常重要的细节。Django中为了给一个应用设计URL,需要创建一个Python模块,通常称为URLconf(URL configuration,就是前面的urls.py
).
这个模块是纯粹的Python代码,它包含URL模式(简单的正则表达式)到Python函数或类(views.py
中的函数或类)的简单映射。
下面是一个简单的例子:mysite/urls.py
from django.conf.urls import include, url
from . import views
urlpatterns = [
# url(r'^admin/', include(admin.site.urls)),
url(r'^$', views.index, name="index"),
url(r'^sample/', include('sample.urls', namespace="sample")),
]
sample/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^([0-9]{2})$', views.show_1, name='show_1'),
url(r'^(?P<year>[0-9]{4})', views.show_2, name='show_2'),
]
- 在任何时候,urlpatterns都可以包含其他URLconf模块。这实际上是将包含的URL放置在此处。例如在上面中,把APP中的URLconf包含在ROOT_URLCONF中。
- 上面的示例中使用简单的正则表达式对URL进行匹配,符合Python的正则表达式语法。例如,可以通过圆括号来捕获URL中的值并以位置参数传递给视图,通过命名正则表达式组(?P<name>pattern),其中name是组的名字,pattern是要匹配的模式,来传递命名参数给视图。
- 匹配按照顺序从上往下进行,直到匹配到满足的结束。
模板语言
Django的模板系统将页面的设计从Python中分离出来,前台页面只需接收后台视图传递过来的数据,动态地展示页面。templates/navbar.html
1
<html>
<head><title>{% block title %}{% endblock %}</title></head>
<body>
{% block content %}{% endblock content %}
</body>
</html>
templates/sample/show.html
1
{% extends "navbar.html" %}
{% block title %} Sample Page {% endblock %}
{% block content %}
{% if index %}
<p>I am sample!</p>
{% else%}
{% if value|length_is:"4" %}
<p>The year is {{ value }}</p>
{% elif value|length_is:"2" %}
<p>The month is {{ value }}</p>
{% endif %}
{% endif %}
<p>My name is {{ info.name }}, enrolled in {{ info.enroll }}.</p>
{# I am comments. #}
{% endblock %}
- {{ variable }} 表示一个变量,当模版引擎遇到一个变量,它将计算这个变量,然后用结果替换掉它本身。变量的命名包括任何字母数字以及下划线 (“_”)的组合。点(“.”) 也在会变量部分中出现,不过它有特殊的含义,当模板系统遇到点(“.”),它将以这样的顺序查询:
- 字典查询
- 属性或方法查询
- 数字索引查询
- Django自带了大约24个内置的模版标签。可以在内置标签参考手册中阅读全部关于它们的内容。
- {{ value|length_is:"4" }} 表示一个过滤器,Django提供了大约六十个内置的模版过滤器。你可以在内置过滤器参考手册中阅读全部关于它们的信息。
- 表示一个单行注释, {% comment %}和{% endcomment %}表示多行注释,之间的内容会被忽略。
- {% csrf_token %} 是一个跨站请求伪造保护标签,在提交表单中需要添加。
- {% extends "*.html" %} 表示一个模板继承标签,当模板系统处理这个模板时,首先,它将定位父模板,并用子模板中的内容来替换父模板中的block标签中的内容。
视图模块
一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你的Python目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了能够把代码放在某个地方,惯例是把视图放在叫做views.py的文件中,然后把它放到你的项目或者应用目录里。sample/views.py
from django.shortcuts import render
def index(request):
return render(request, 'sample/show.html', {
'index': True
})
def show_1(request, month):
return render(request, 'sample/show.html', {
'value': month
})
def show_2(request, year):
info = {'name': 'newbie', 'enroll': year}
return render(request, 'sample/show.html', {
'value': year,
'info': info,
})
视图模块主要是进行业务逻辑的处理,然后返回一个HttpResponse对象。
主要介绍一下表单。
HTML表单
在HTML中,表单是位于<form>…</form> 之间的元素的集合,它们允许访问者输入文本、选择选项、操作对象和控制等等,然后将信息发送回服务器。
处理表单是一件很复杂的事情。考虑一下Django 的Admin 站点,不同类型的大量数据项需要在一个表单中准备好、渲染成HTML、使用一个方便的界面编辑、返回给服务器、验证并清除,然后保存或者向后继续处理。
Django 的表单功能可以简化并自动化大部分这些工作,而且还可以比大部分程序员自己所编写的代码更安全。
Django 会处理表单工作中的三个显著不同的部分:
- 准备并重新构造数据
- 为数据创建HTML 表单
- 接收并处理客户端提交的表单和数据
可以手工编写代码来实现,但是Django 可以帮你完成所有这些工作。
在Django中构建一个表单sample/forms.py
1
from django import forms
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100, required=True)
age = forms.IntegerField(initial=0)
表单系统的核心部分是Django的Form类.Django 的模型描述一个对象的逻辑结构、行为以及展现给我们的方式,与此类似,Form 类描述一个表单并决定它如何工作和展现.
就像模型类的属性映射到数据库的属性一样,表单类的字段会映射到HTML 的<input>表单的元素.
表单的字段本身也是类;它们管理表单的数据并在表单提交时进行验证。
templates/sample/form.html
1
{% extends "base.html" %}
{% block title %} Sample Page {% endblock %}
{% block content %}
<form action="{% url 'sample:get_name' %}" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
{% endblock %}
sample/views.py
1
from .forms import NameForm
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
name = form.cleaned_data['your_name']
age = form.cleaned_data['age']
return render(request, 'sample/success.html', {
'name': name,
'age': age
})
else:
form = NameForm()
return render(request, 'sample/form.html', {'form': form})
sample/success.html
1
<html>
<head><title>Success</title>title></head>
<body>
<p>Success!</p>
<p>Your name is {{ name }}, aged {{ age }}.</p>
<a href='{% url 'sample:get_name' %}'>返回</a>
</body>
</html>
建立数据库连接
由于我们需要从数据库中读取我们抓取的热点新闻信息,所以需要连接数据库,这里我们采用MYSQL.
在project_name/settings.py中默认的数据库是Python自带的SQLite3,所以我们需要修改一下配置.
settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # database engine
'NAME': 'nust_visual_platform', # schema name
'USER': 'root', # mysql username
'HOST': 'localhost', # mysql host
'PASSWORD': '', # mysql password
'PORT': '3306'} # mysql port
}
我们需要在MYSQL中新建一个schema,剩下的所有对数据库的操作都不需要我们手动处理,Django会为我们代劳.
新建一个数据库表:
在
wangyi
下面新建models.py
模型文件,然后在文件中定义我们的数据库表.1
from django.db import models class WangyiArticle(models.Model): docid = models.CharField(primary_key=True, max_length=50) votecount = models.IntegerField(default=0) content = models.TextField() ptime = models.DateTimeField()
具体细节可查看Django提供的全部模型字段的字段选项和字段类型的API。
2.运行命令来生成产生数据表的SQL代码.1
python manage.py makemigrations wangyi
我们可以看到类似下面的信息:
Migrations for 'wangyi':
0001_initial.py:
- Create model WangyiArticle
3.在数据库中生成数据表1
python manage.py migrate wangyi
如果你的数据库中其实已经有这张表存在了,就不要执行SQL去改变数据表,这时需要运行1
python manage.py migrate wangyi --fake-initial
4.对数据表进行URD操作
对数据表的操作可以在models.py
中也可以在views.py
中,这里我们只介绍如何在views.py
中操作数据表.
遍历数据表:1
WangyiArticle.objects
对获取的数据进行筛选:1
WangyiArticle.objects.filter(ptime__lt=today)
.filter(mtime__gel=yesterday)
.filter(parent_id='')
.order_by('-votecount')[:10]
Django的ORM(Object Relational Mapping)功能很强大,具体的其他细节可以参考官方文档
自动分页功能
1. 安装
1 | pip install python-pagination |
2. 配置
说明:django1.4开始,TEMPLATE_CONTEXT_PROCESSORS
不显示在settings.py
文件中,此时需要自己添加
在settings.py
开头添加1
import django.conf.global_settings as DEFAULT_SETTINGS
在配置最后添加1
2
3
4
5
6
7TEMPLATE_CONTEXT_PROCESSORS = DEFAULT_SETTINGS.TEMPLATE_CONTEXT_PROCESSORS + (
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.request",
)
3. 修改默认样式
将site-packages/pagination/templates/pagination/pagination.html
文件复制
到your_own_templates/pagination/pagination.html
,然后修改这个文件就可以了.
4. 参阅资料
Bootstrap
Bootstrap,来自 Twitter,是目前很受欢迎的前端框架。Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷,是非专业网站开发人员优雅展示自己成果的利器。
Bootstrap是基于HTML5和CSS3开发的,它在jQuery的基础上进行了更为个性化和人性化的完善,形成一套自己独有的网站风格,并兼容大部分jQuery插件。
Bootstrap中包含了丰富的Web组件,根据这些组件,可以快速的搭建一个漂亮、功能完备的网站。其中包括以下组件:
下拉菜单、按钮组、按钮下拉菜单、导航、导航条、路径导航、分页、排版、缩略图、警告对话框、进度条、媒体对象等。
我们可以很方便的把Bootstrap加入到我们的网站之中,以上面的项目为例。templates/base.html
1
<html>
<head>
<title>{% block title %}{% endblock %}</title>
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static 'base/css/bootstrap.min.css' %}"/>
<script src="{% static 'base/js/jquery-2.1.4.min.js' %}"></script>
<script src="{% static 'base/js/bootstrap.min.js' %}"></script>
</head>
<body>
{% block content %}{% endblock content %}
</body>
</head>
只需要把bootstrap的css文件引入HTML中就可以使用它的CSS样式,但是必须在引入bootstrap.js文件之前先引入jQuery文件才能使用javascript插件。
在这里说一下Django的静态文件。
除了由服务器生成的HTML文件外,网页应用一般需要提供其它必要的文件 —— 比如图片文件、JavaScript脚本和CSS样式表 —— 来为用户呈现出一个完整的网站。 在Django中,我们将这些文件称为“静态文件”。
首先在mysite中创建一个static目录.Django将在那里查找静态文件,这与Django是如何在templates
中寻找对应的模板文件的方式是一致的.需要在配置文件中设置静态文件查找目录.settings.py
1
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.getcwd() + '/static/',
)
1 | <!-- Standard button --> <button type="button" class="btn btn-default">(默认样式)Default</button> <!-- Provides extra visual weight and identifies the primary action in a set of buttons --> <button type="button" class="btn btn-primary">(首选项)Primary</button> <!-- Indicates a successful or positive action --> <button type="button" class="btn btn-success">(成功)Success</button> <!-- Contextual button for informational alert messages --> <button type="button" class="btn btn-info">(一般信息)Info</button> <!-- Indicates caution should be taken with this action --> <button type="button" class="btn btn-warning">(警告)Warning</button> <!-- Indicates a dangerous or potentially negative action --> <button type="button" class="btn btn-danger">(危险)Danger</button> <!-- Deemphasize a button by making it look like a link while maintaining button behavior --> <button type="button" class="btn btn-link">(链接)Link</button> |
E-charts
ECharts,缩写来自Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼容当前绝大部分浏览器(IE6/7/8/9/10/11,chrome,firefox,Safari等),底层依赖轻量级的Canvas类库ZRender,提供直观,生动,可交互,可高度个性化定制的数据可视化图表。创新的拖拽重计算、数据视图、值域漫游等特性大大增强了用户体验,赋予了用户对数据进行挖掘、整合的能力。
支持折线图(区域图)、柱状图(条状图)、散点图(气泡图)、K线图、饼图(环形图)、雷达图(填充雷达图)、和弦图、力导向布局图、地图、仪表盘、漏斗图、事件河流图等12类图表,同时提供标题,详情气泡、图例、值域、数据区域、时间轴、工具箱等7个可交互组件,支持多图表、组件的联动和混搭展现。
以我们的项目为例,可以很方便的使用Echarts进行数据可视化。templates/sample/echarts.html
1
{% extends "base.html" %}
{% block title%}ECharts{% endblock %}
{% block content %}
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="height:400px"></div>
<!-- ECharts文件引入 -->
<script src="http://echarts.baidu.com/build/dist/echarts-all.js"></script>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts图表
var myChart = echarts.init(document.getElementById('main'));
var option = {
tooltip: {
show: true
},
legend: {
data:['销量']
},
xAxis : [
{
type : 'category',
data : ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
}
],
yAxis : [
{
type : 'value'
}
],
series : [
{
"name":"销量",
"type":"bar",
"data":{{ data }}
}
]
};
// 为echarts对象加载数据
myChart.setOption(option);
</script>
{% endblock %}
效果如下:
1 | <!-- 为ECharts准备一个具备大小(宽高)的Dom --> <div id="main1" style="height:400px; width: 80%; margin-left: 10%;"></div> <!-- ECharts文件引入 --> <script src="http://echarts.baidu.com/build/dist/echarts-all.js"></script> <script type="text/javascript"> // 基于准备好的dom,初始化echarts图表 option1 = { title : { text: '某站点用户访问来源', subtext: '纯属虚构', x:'center' }, tooltip : { trigger: 'item', formatter: "{a} <br/>{b} : {c} ({d}%)" }, legend: { orient : 'vertical', x : 'left', data:['直接访问','邮件营销','联盟广告','视频广告','搜索引擎'] }, toolbox: { show : true, feature : { mark : {show: true}, dataView : {show: true, readOnly: false}, magicType : { show: true, type: ['pie', 'funnel'], option: { funnel: { x: '25%', width: '50%', funnelAlign: 'left', max: 1548 } } }, restore : {show: true}, saveAsImage : {show: true} } }, calculable : true, series : [ { name:'访问来源', type:'pie', radius : '55%', center: ['50%', '60%'], data:[ {value:335, name:'直接访问'}, {value:310, name:'邮件营销'}, {value:234, name:'联盟广告'}, {value:135, name:'视频广告'}, {value:1548, name:'搜索引擎'} ] } ] }; // 为echarts对象加载数据 var myChart = echarts.init(document.getElementById('main1')); myChart.setOption(option1); </script> |