Django网站快速入门
2.1 个人博客网站规划
个人博客具有以下功能:
- 项目名称mblog
- 通过admin管理界面张贴、编辑以及删除贴文
- 使用Bookstrap网页框架
- 在主页中显示每篇文章的标题,及发帖日期
创建项目:
django-admin startproject mblog
cd mblog
python mange.py startapp mainsite
在setting.py中加入'mainsite'
2、创建博客数据表
python manage.py migrate
Django要使用数据库,有以下几个步骤:
- 在models.py中定义需要使用的类(继承自models.Models)
- 详细地设置每一个在类中的变量,即数据表中的每一个字段
- 使用
python manage.py makemigrations mainsite
创建数据库和Django间的中间文件 - 使用
python manage.py migrate
同步更新数据库的内容 - 在程序中使用python的操作方法所定义的数据类,等于是在操作数据库中的数据表
修改mainsite/models.py内容
from django.db import models
from django.utils import timezone
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=200)
slug = models.CharField(max_length=200)
body = models.TextField()
pub_date = models.DateTimeField(default=timezone.now)
class Meta:
ordering = ('-pub_date',)
def __unicode__(self):
return self.title
注:创建一个post类(到时候在数据库中会有一个对应的数据表)。此类包含几个项目,title-题目;slug-网址;body-内容;pub-date-发表的时间。
Class Meta 内的设置是指定文章显示的顺序是以pub_date为依据。unicode提供此类所产生的数据型,一个以文章标题作为显示的内容,增加操作过程中的可读性,使用unicode而不是str,让标题支持中文。
pub_date需要一个pytz模块,执行pip install pytz
安装
让此模型生效,执行:
python manage.py makemigrations
创建管理员账号和密码:
python manage.py createsuperuser
把前面定义的post
纳入管理:修改mainsite/admin.py
,并且加上张贴日期和时间等内容:
from django.contrib import admin
from .models import Post
# Register your models here.
class PostAdmin(admin.ModelAdmin):
list_display = ('title','slug','pub_date')
admin.site.register(Post,PostAdmin)
使用*.*.*.*:8000\admin
访问,创建至少五篇文章,方便后续测试。
简单说明一下Django的MTV架构(类比MVC)。Django把数据的存取和显示分为Model、Template以及View。分别对应models.py、template文件夹以及view.py文件。
- Model——model.py:主要负责定义要存取的数据类型,以Python的class类来定义,在后端Django会自动把这个类中的设置对应的到数据库系统中,不管使用的是哪一种数据库。
- View——view.py:负责如何把这些数据存进去或取出等程序逻辑。
- Template——template文件夹:负责把取得的数据用美观且有弹性的方式输出。
编辑mainsite/admin.py
from django.contrib import admin
from .models import Post
# Register your models here.
class PostAdmin(admin.ModelAdmin):
list_display = ('title','slug','pub_date')
admin.site.register(Post,PostAdmin)
root@django:~/mblog# vim mainsite/views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Post
# Create your views here.
def homepage(request):
posts = Post.objects.all()
post_lists = list()
for count, post in enumerate(posts):
post_lists.append(No.{}".format(str(count))+str(post)+"<hr>")
post_lists.append("<small>"+str(post.body.encode('utf-8'))\+"</small><br><br>")
return HttpResponse(post_lists)
首先,把model.py中自定义的Model导入,然后使用Post.objects.all()取得所有数据项,然后可用for循环取出所有内容,再通过HttpResponse输出到网页上。
此例中,创建了一个homepage函数来获取所有文章,并通过循环吧它们和搜集到变量post_lists中,最后使用`return HttpResponse(post_lists)把这个变量的内容输出到用户端的浏览器页面中。
然后由urls.py
负责调用这个函数。url.py
负责网址和程序间的对应工作。打开urls.py
导入来自views.py
的homepage函数并以url对应。
from django.conf.urls import include, url
from django.contrib import admin
from mainsite.views import homepage, showpost
urlpatterns = [
url(r'^$', homepage),
url(r'^admin/', include(admin.site.urls)),
]
写程序时,显示的样子和如何存储数据或资料内容要分来才比较容易维护,
因此,正确的做法是在views.py
中把数据或资料准备好,然后放到template
中,让template
中的.html
文件负责真正显示的工作。
2.3 网址对应于页面输出
如何把前面拿到的数据变得更加美观?答案是通过模板template。每一个输出的网页都可以准备一个或以上对应的模板,这些模板以.html
的文件形式存储在指定的文件夹中,当网站有数据需要输出时,通过渲染函数(render)把数据存放到模板指定的位置中,得到结果后再交给HttpResponse输出给浏览器。
基本步骤如下:
- 在
setting.py
中设置模板文件夹的位置 - 在
url.py
中创建网址和view.py
中函数的对应关系 - 创建
.html
文件(例如index.html),做好排版并安排数据要防止的位置 - 运行程序,以
objects.all()
在views.html
中取得数据或资料 - 以render函数把数据(例如posts)送到指定的模板文件(例如index.html)中
创建templates文件夹,然后把此文件夹名称加到settings.py的TEMPLTE区块中(只需修改DIRS所在行即可):
'DIRS': [os.path.join(BASE_DIR, 'templates')],
然后把post和now放到模板(例index.html)中显示,把views.py
修改如下:
from django.template.loader import get_template
from django.http import HttpResponse
from datetime import datetime
from .models import Post
# Create your views here.
def homepage(request):
template = get_template('index.html')
posts = Post.objects.all()
now = datetime.now()
html = template.render(locals())
return HttpResponse(html)
这里使用了一个小技巧把变量放到模板中,就是使用local()函数。这个函数会把当前内存中的所有局部变量使用字典类型打包起来。在模板中因为接收到了所有局部变量,所有也可以把posts和now都拿来使用。
在templates
目录下,创建一个名为index.html
的模板文件:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>
欢迎观临我的博客
</title>
</head>
<body>
<h1>欢迎观临我的博客</h1>
<hr>
{% for post in posts %}
<p style='font-family:微软雅黑;font-size:14pt;font-weight:bold;'>
<a href='/post/'{{post.slug}}'>{{ post.title }}</a>
</p>
<% endfor %>
<hr>
<h3>现在时刻:{{ now }}</h3>
</body>
</html>
使用{{}}用来输出收到的数据,每一个数据项的字段都是以post.body、post.title的方式取出。
通过<a href>
HTML标签取出post.slug,创建为链接网址,并放在post/下。
网址对应url.py
要识别这些网址以便对应到要显示的单篇文章内容,有如下几步:
- 在
url.py
中设置,只要是/post/开头的网址,就把后面接着的文字当做参数传送slug给post_detail显示单篇文章的函数。 - 在
view.py
中新增一个post_detail
函数,除了接受request参数外,也接受slug参数 - 在templates文件夹中创建一个用来显示单篇文章的post.html
- 在
post_detail
函数中,以slug为关键字搜索数据集,找出是否有符合的项目 - 如果有,就把找到的数据项传送给render函数,找出
post.html
模板页进行渲染(即进行网页显示),再把结果交给HttpResponse回传给浏览器 - 如果没有符合的项目,就把网页传回首页
mblog/urls.py
做如下修改:
from django.conf.urls import include, url
from django.contrib import admin
from mainsite.views import homepage, showpost
urlpatterns = [
url(r'^$', homepage),
url(r'^post/(\w+)$', showpost),
url(r'^admin/', include(admin.site.urls)),
]
把所有/post开头的网址都找出来,作为当做第二个参数(第一个是默认的request)传给showpost函数。
同时在views.py中新建这个函数来处理收到的参数,内容如下:
from django.template.loader import get_template
from django.http import HttpResponse
from datetime import datetime
from .models import Post
from django.shortcuts import redirect
# Create your views here.
...
def showpost(request, slug):
template = get_template('post.html')
try:
post = Post.objects.get(slug=slug)
if post != None:
html = template.render(locals())
return HttpResponse(html)
except:
return redirect('/')
加上意外处理,在搜索发生意外时以redirect(‘/’)的方式直接返回首页。
显示文章的post.html
内容如下
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>
欢迎观临我的博客
</title>
</head>
<body>
<h1>{{ post.title }}</h1>
<hr>
<p style='font-family:微软雅黑;font-size:12pt;letter-spacing:2pt;'>
{{ post.body }}
</p>
<hr>
<h3><a href='/'>回首页</a></h3>
</body>
</html>