Django学习(二)——实现个人博客网站

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>

猜你喜欢

转载自blog.csdn.net/qq_23348071/article/details/77164561
今日推荐