ORM的魔法
今天我们的主要目标,是将我们通过后台管理界面添加的数据,填充到前台页面中。我们首先需要解决的问题是,怎么调用数据库中的内容?像ASP时代一样通过ADOConnection和RecordSet么?或者像ASP.net一样通过SqlConnection和SqlCommand?No,No,No,那些传统的方式都弱爆了好吗?Django提供了强大的ORM功能,可以通过函数调用的方式完成数据库的增删改查,Django可以自动将函数调用转换成数据库相关操作,再将操作结果以对象的方式返回给我们。
我们还是通过实际代码来感受一下吧,打开命令行工具,进入DjangoQuickTour所在的目录,输入如下命令:
python manage.py shell
manage.py将调用python,并自动设置相关的环境变量。当然,如果想通过“手动档”的方式来搞定,可以先运行python,然后在其中调用:
import django
django.setup()
结果是一样一样的,这里还是建议大家通过前一种“自动档”的方式,汪嘿嘿。
接下来,我们需要引入我们在blog应用中申明的模型类:
>>> from blog.models import Article
然后,我们就可以试用Django提供的ORM功能了,比如,把所有的文章列出来看看:
>>> Article.objects.all()
命令行返回了下面的结果:
, , , , , , , , ]>
哇偶,这个真的很好很强大,我们再来试试这个:
print Article.objects.all().count()
命令行返回9,汪咔咔,这个没错!
接下来,我们来玩儿点更加复杂的,比如:
>>> article = Article.objects.get(id = 1)
>>> article
>>> articleSet = Article.objects.filter(title__startswith = u'跟着大狗')
>>> articleSet
]>
>>> articleSet = Article.objects.filter(title__icontains = u'吃')
>>> articleSet
, ]>
>>> articleSet = Article.objects.exclude(author = u'大狗')
>>> articleSet
, ]>
>>> orderedArticles = Article.objects.all().order_by('-timestamp')
>>> orderedArticles
, , , , , , , , ]>
>>> authors = Article.objects.all().values('author').distinct()
>>> for author in authors:
... print author['author']
...
大狗
匿名
妹纸
Django的ORM简直太强大了,不需要关心数据库连接,不需要关心数据集,一条函数调用,简单而直接。
下面大狗把上面用到的ORM功能简单的解释一下:
- all(): 得到所有的数据记录
- get(): 得到首条符合查询条件的数据记录
- fliter(): 得到所有符合查询条件的数据记录
- exclude(): 排除符合查询条件的数据记录(相当于SQL语句中的NOT)
- order_by(): 按指定字段排序,如果字段名前加减号“-”,就是降序排列
- values(): 仅返回指定的字段值
- distinct(): 过滤重复数据
完整的功能介绍,请参见 Django Documentation: Making queries
构建首页
现在我们可以试着从首页开始,构建我们的博客了。首先,打开位于blog应用templates子目录中的首页模板index.html,做一点小小的修改:
欢迎光临「大狗汪叨叨」
大狗汪叨叨
{% for article in all_articles %}
{{article.title}}
by: {{article.author}} {{article.timestamp}}
{{article.body}}
{% endfor %}
接下来,我们还需要修改一下blog应用中的views.py文件,将需要显示的博客文章放入上下文字典的all_articles项中,以便在模板文件中利用传入的博客文章完成页面渲染:
# encoding:utf-8
from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader
from blog.models import *
def index(reqeust):
template = loader.get_template('blog/index.html')
allArticles = Article.objects.all().order_by('-timestamp')
context = {
'all_articles' : allArticles,
}
return HttpResponse(template.render(context, reqeust))
让我们把开发服务器跑起来,看下效果:
额,果然把我们通过后台管理添加的博客内容显示出来了,然而页面简直丑爆了,而且我们在后台管理中添加的换行呢?
经过查询文档,才指定Django默认会屏蔽文本字段中的换行符,解决的方法居然非常非常的简单,我们只需要将模板文件中的“article.body”后面加上“|linebreaks”就可以了:
CSS和图片
常见的网站中,除了HTML文件以外,我们还需要包含CSS,图片,JavaScript文件等静态文件。对基于Django的网站而言,内置的django.contrib.staticfiles可以将项目中每个应用中的静态文件“收集”起来,映射到一个统一位置,以便项目中的各个页面调用。
和模板文件的处理方式类似,我们需要在blog目录中创建static目录,并在其中创建blog子目录,为便于管理,我们可以为CSS和图片各创建一个独立的目录。大狗在CSS目录中创建了一个名称为style.css的文件,内容如下:
body{
background-color: #FFFFAA;
}
.pageTitle{
font-family: 黑体;
font-size: 50px;
font-weight: bold;
text-decoration: none;
color: #888888;
}
.articleTitle{
font-family: 宋体;
font-size: 20px;
font-weight: bold;
text-decoration: none;
color: blue;
}
.articleAuthor{
font-family: 宋体;
font-size: 14px;
font-weight: bold;
text-decoration: none;
font-style: italic;
color: black;
}
.articleBody{
font-family: 宋体;
font-size: 12px;
font-weight: normal;
text-decoration: none;
color: black;
}
然后在图片目录中放了一个小狗狗logo。现在,我们的项目文件目录结构是这样的:
.
├── DjangoQuickTour
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── settings.py
│ ├── settings.pyc
│ ├── urls.py
│ ├── urls.pyc
│ ├── wsgi.py
│ └── wsgi.pyc
├── blog
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── admin.py
│ ├── admin.pyc
│ ├── apps.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── 0001_initial.pyc
│ │ ├── __init__.py
│ │ └── __init__.pyc
│ ├── models.py
│ ├── models.pyc
│ ├── static
│ │ └── blog
│ │ ├── css
│ │ │ └── style.css
│ │ └── images
│ │ └── logo.jpeg
│ ├── templates
│ │ └── blog
│ │ ├── index.html
│ │ └── style.css
│ ├── tests.py
│ ├── urls.py
│ ├── urls.pyc
│ ├── views.py
│ └── views.pyc
├── db.sqlite3
└── manage.py
接下来,我们还需要把模板文件(/blog/templates/blog/index.html)稍稍修改一下:
{% load static %}
欢迎光临「大狗汪叨叨」
![]({% static 'blog/images/logo.jpeg' %})
大狗汪叨叨
{% for article in all_articles %}
{{article.title}}
by: {{article.author}} {{article.timestamp}}
{{article.body|linebreaks}}
{% endfor %}
如果需要在模板文件中引用静态文件,首先需要在页面起始部分添加如下声明,以便Django引用相关模块:
{% load static %}
页面中需要引用静态文件的部分,则采用如下的格式:
{% static '文件路径' %}
其中文件路径,是从项目static目录起始的相对路径。
完成修改后。我们可以启动开发服务器看一下效果,是不是比开始漂亮多了?
在下一篇笔记中,我们将对博客网站进行下一步的修改,在首页中仅显示文章概要,在单独的页面中显示文章内容,我们还会增加按类别、作者和日期查询文章的功能。