django搭建个人博客

Posted brafei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django搭建个人博客相关的知识,希望对你有一定的参考价值。

为你的模型(models)创建一个管理站点

现在我们已经定义好了Post模型(model),我们将要创建一个简单的管理站点来管理blog帖子。Django内置了一个管理接口,该接口对编辑内容非常的有用。这个Django管理站点会根据你的模型(model)元数据进行动态构建并且提供一个可读的接口来编辑内容。你可以对这个站点进行自由的定制,配置你的模型(models)在其中如何进行显示。

请记住,django.contrib.admin已经被包含在我们项目的INSTALLED_APPS设置中,我们不需要再额外添加。

创建一个超级用户

首先,我们需要创建一名用户来管理这个管理站点。运行以下的命令:

python manage.py createsuperuser

你会看下以下输出。输入你想要的用户名,邮箱和密码:

Username (leave blank to use 'admin'): adminEmail address: admin@admin.comPassword: ********Password (again): ********
Superuser created successfully.

Django管理站点

现在,通过python manage.py runserver命令来启动开发服务器,之后在浏览器中打开 http://127.0.0.1:8000/admin/ 。你会看到管理站点的登录页面,如下所示:

使用你在上一步中创建的超级用户信息进行登录。你将会看到管理站点的首页,如下所示:

GroupUser 模型(models) 位于django.contrib.auth,是Django权限管理框架的一部分。如果你点击Users,你将会看到你之前创建的用户信息。你的blog应用的Post模型(model)和User(model)关联在了一起。记住,它们是通过author字段进行关联的。

在管理站点中添加你的模型(models)

让我们在管理站点中添加你的blog模型(models)。编辑blog应用下的admin.py文件,如下所示:

from django.contrib import adminfrom .models import Post

admin.site.register(Post)

现在,在浏览器中刷新管理站点。你会看到你的Post模型(model)已经在页面中展示,如下所示:

这很简单,对吧?当你在Django的管理页面注册了一个模型(model),Django会通过对你的模型(models)进行内省然后提供给你一个非常友好有用的接口,这个接口允许你非常方便的排列,编辑,创建,以及删除对象。

点击Posts右侧的Add链接来添加一篇新帖子。你将会看到Django根据你的模型(model)动态生成了一个表单,如下所示:

Django给不同类型的字段使用了不同的表单控件。即使是复杂的字段例如DateTimeField也被展示成一个简单的接口类似一个javascript日期选择器。

填写好表单然后点击Save按钮。你会被重定向到帖子列页面并且得到一条帖子成功创建的提示,如下所示:

定制models的展示形式

现在我们来看下如何定制管理站点。编辑blog应用下的admin.py文件,使之如下所示:

from django.contrib import adminfrom .models import Postclass PostAdmin(admin.ModelAdmin):
    list_display = ('title', 'slug', 'author', 'publish',                    'status')
admin.site.register(Post, PostAdmin)

我们使用继承了ModelAdmin的定制类来告诉Django管理站点中需要注册我们自己的模型(model)。在这个类中,我们可以包含一些关于如何在管理站点中展示模型(model)的信息以及如何与该模型(model)进行交互。list_display属性允许你在设置一些你想要在管理对象列表页面显示的模型(model)字段。

让我们通过更多的选项来定制管理模型(model),如使用以下代码:

class PostAdmin(admin.ModelAdmin):
    list_display = ('title', 'slug', 'author', 'publish',                    'status')
    list_filter = ('status', 'created', 'publish', 'author')
    search_fields = ('title', 'body')
    prepopulated_fields = {'slug': ('title',)}
    raw_id_fields = ('author',)
    date_hierarchy = 'publish'
    ordering = ['status', 'publish']

回到浏览器刷新管理站点页面,现在应该如下所示:

你可以看到帖子列页面中展示的字段都是你在list-dispaly属性中指定的。这个列页面现在包含了一个右侧边栏允许你根据list_filter属性中指定的字段来过滤返回结果。一个搜索框也应用在页面中。这是因为我们还通过使用search_fields属性定义了一个搜索字段列。在搜索框的下方,有个可以通过时间层快速导航的栏,该栏通过定义date_hierarchy属性出现。你还能看到这些帖子默认的通过StatusPublish列进行排序。这是因为你通过使用ordering属性指定了默认排序。

现在,点击Add post链接。你还会在这儿看到一些改变。当你输入完成新帖子的标题,slug字段将会自动填充。我们通过使用prepoupulated_fields属性告诉Django通过输入的标题来填充slug字段。同时,现在的author字段展示显示为了一个搜索控件,这样当你的用户量达到成千上万级别的时候比再使用下拉框进行选择更加的人性化,如下图所示:

通过短短的几行代码,我们就在管理站点中自定义了我们的模型(model)的展示形式。还有更多的方式可以用来定制Django的管理站点。在这本书的后面,我们还会进一步讲述。

使用查询集(QuerySet)和管理器(managers)

现在,你已经有了一个完整功能的管理站点来管理你的blog内容,是时候学习如何从数据库中检索信息并且与这些信息进行交互了。Django自带了一个强大的数据库抽象API可以让你轻松的创建,检索,更新以及删除对象。Django的Object-relational Mapper(ORM)可以兼容mysql,PostgreSQL,SQLite以及Oracle。请记住你可以在你项目下的setting.py中编辑DATABASES设置来指定数据库。Django可以同时与多个数据库进行工作,这样你可以编写数据库路由通过任何你喜欢的方式来操作数据。

一旦你创建好了你的数据模型(models),Django会提供你一个API来与它们进行交互。你可以找到数据模型(model)的官方参考文档通过访问 https://docs.djangoproject.com/en/1.8/ref/models/ 。

创建对象

打开终端运行以下命令来打开Python shell:

python manage.py shell

然后依次输入以下内容:

>>> from django.contrib.auth.models import User>>> from blog.models import Post>>> user = User.objects.get(username='admin')>>> post = Post.objects.create(title='One more post',
                        slug='one-more-post',
                        body='Post body.',
                        author=user)>>> post.save()

让我们来研究下这些代码做了什么。首先,我们取回了一个username是admin的用户对象:

user = User.objects.get(username='admin')

get()方法允许你从数据库取回一个单独的对象。注意这个方法只希望在查询中有唯一的一个匹配。如果在数据库中没有返回结果,这个方法会抛出一个DoesNotExist异常,如果数据库返回多个匹配结果,将会抛出一个MultipleObjectsReturned异常。当查询执行的时候,所有的异常都是模型(model)类的属性。

接着,我们来创建一个拥有定制标题标题,slug和内容的Post实例,然后我们设置之前取回的user胃这篇帖子的作者如下所示:

post = Post(title='Another post', slug='another-post', body='Postbody.', author=user)

这个对象只是存在内存中不会执行到数据库中

最后,我们通过使用save()方法来保存该对象到数据库中:

post.save()

这步操作将会执行一段SQL的插入语句。我们已经知道如何在内存中创建一个对象并且之后才在数据库中进行插入,但是我们也可以通过使用create()方法直接在数据库中创建对象,如下所示:

Post.objects.create(title='One more post', slug='one-more-post',body='Post body.', author=user)

更新对象

现在,改变这篇帖子的标题并且再次保存对象:

>>> post.title = 'New title'>>> post.save()

这一次,save()方法执行了一条更新语句。

你对对象的改变一直存在内存中直到你执行到save()方法。

取回对象

Django的Object-relational mapping(ORM)是基于查询集(QuerySet)。查询集(QuerySet)是从你的数据库中根据一些过滤条件范围取回的结果对象进行的采集。你已经知道如何通过get()方法从数据库中取回单独的对象。如你所见:我们通过Post.objects.get()来使用这个方法。每一个Django模型(model)至少有一个管理器(manager),默认管理器(manager)叫做objects。你通过使用你的模型(models)的管理器(manager)就能获得一个查询集(QuerySet)对象。获取一张表中的所有对象,你只需要在默认的objects管理器(manager)上使用all()方法即可,如下所示:

>>> all_posts = Post.objects.all()

这就是我们如何创建一个用于返回数据库中所有对象的查询集(QuerySet)。注意这个查询集(QuerySet)并还没有执行。Django的查询集(QuerySets)是惰性(lazy)的,它们只会被动的去执行。这样的行为可以保证查询集(QuerySet)非常有效率。如果我们没有把查询集(QuerySet)设置给一个变量,而是直接在Python shell中编写,因为我们迫使它输出结果,这样查询集(QuerySet)的SQL语句将立马执行:

>>> Post.objects.all()

使用filter()方法

为了过滤查询集(QuerySet),你可以在管理器(manager)上使用filter()方法。例如,我们可以返回所有在2015年发布的帖子,如下所示:

Post.objects.filter(publish__year=2015)

你也可以使用多个字段来进行过滤。例如,我们可以返回2015年发布的所有作者用户名为admin的帖子,如下所示:

Post.objects.filter(publish__year=2015, author__username='admin')

上面的写法和下面的写法产生的结果是一致的:

Post.objects.filter(publish__year=2015).filter(author__username='admin')

我们构建了字段的查找方法,通过使用两个下划线(publish__year)来查询,除此以外我们也可以通过使用两个下划线(author__username)访问关联的模型(model)字段。

使用exclude()

你可以在管理器(manager)上使用exclude()方法来排除某些返回结果。例如:我们可以返回所有2015年发布的帖子但是这些帖子的题目开头不能是Why:

Post.objects.filter(publish__year=2015).exclude(title__startswith='Why')

使用order_by()

通过在管理器(manager)上使用order_by()方法来对不同的字段进行排序,你可以对结果进行排序。例如:你可以取回所有对象并通过它们的标题进行排序:

Post.objects.order_by('title')

默认是升序。你可以通过负号来指定使用降序,如下所示:

Post.objects.order_by('-title')

删除对象

如果你想删除一个对象,你可以对对象实例进行下面的操作:

post = Post.objects.get(id=1)
post.delete()

请注意,删除对象也将删除任何的依赖关系

查询集(QuerySet)什么时候会执行

只要你喜欢,你可以连接许多的过滤给查询集(QuerySet)而且不会立马在数据库中执行直到这个查询集(QuerySet)被执行。查询集(QuerySet)只有在以下情况中才会执行:
* 在你第一次迭代它们的时候
* 当你对它们的实例进行切片:例如Post.objects.all()[:3]
* 当你对它们进行了打包或缓存
* 当你对它们调用了repr()len()方法
* 当你明确的对它们调用了list()方法
* 当你在一个声明中测试它,例如bool(), or, and, or if

创建model manager

我们之前提到过, objects是每一个模型(models)的默认管理器(manager),它会返回数据库中所有的对象。但是我们也可以为我们的模型(models)定义一些定制的管理器(manager)。我们准备创建一个定制的管理器(manager)来返回所有状态为已发布的帖子。

有两种方式可以为你的模型(models)添加管理器(managers):你可以添加额外的管理器(manager)方法或者继承管理器(manager)的查询集(QuerySets)进行修改。第一种方法类似Post.objects.my_manager(),第二种方法类似Post.my_manager.all()。我们的管理器(manager)将会允许我们返回所有帖子通过使用Post.published

编辑你的blog应用下的models.py文件添加如下代码来创建一个管理器(manager):

class PublishedManager(models.Manager):
    def get_queryset(self):
        return super(PublishedManager,                    self).get_queryset().filter(status='published')    class Post(models.Model):
    # ...
    objects = models.Manager() # The default manager.
    published = PublishedManager() # Our custom manager.

get_queryset()是返回执行过的查询集(QuerySet)的方法。我们通过使用它来包含我们定制的过滤到完整的查询集(QuerySet)中。我们定义我们定制的管理器(manager)然后添加它到Post 模型(model)中。我们现在可以来执行它。例如,我们可以返回所有标题开头为Who的并且是已经发布的帖子:

Post.published.filter(title__startswith='Who')

构建列和详情视图(views)

现在你已经学会了一些如何使用ORM的基本知识,你已经准备好为blog应用创建视图(views)了。一个Django视图(view)就是一个Python方法,它可以接收一个web请求然后返回一个web响应。在视图(views)中通过所有的逻辑处理返回期望的响应。

首先我们会创建我们的应用视图(views),然后我们将会为每个视图(view)定义一个URL模式,我们将会创建html模板(templates)来渲染这些视图(views)生成的数据。每一个视图(view)都会渲染模板(template)传递变量给它然后会返回一个经过渲染输出的HTTP响应。

创建列和详情views

让我们开始创建一个视图(view)来展示帖子列。编辑你的blog应用下中views.py文件,如下所示:

from django.shortcuts import render, get_object_or_404from .models import Postdef post_list(request):
    posts = Post.published.all()    return render(request,                  'blog/post/list.html',
                  {'posts': posts})

你刚创建了你的第一个Django视图(view)。post_list视图(view)将request对象作为唯一的参数。记住所有的的视图(views)都有需要这个参数。在这个视图(view)中,我们获取到了所有状态为已发布的帖子通过使用我们之前创建的published管理器(manager)。

最后,我们使用Django提供的快捷方法render()通过给予的模板(template)来渲染帖子列。这个函数将request对象作为参数,模板(template)路径以及变量来渲染的给予的模板(template)。它返回一个渲染文本(一般是HTML代码)HttpResponse对象。render()方法考虑到了请求内容,这样任何模板(template)内容处理器设置的变量都可以带入给予的模板(template)中。你会在第三章,扩展你的blog应用学习到如何使用它们。

让我们创建第二个视图(view)来展示一篇单独的帖子。添加如下代码到views.py文件中:

def post_detail(request, year, month, day, post):
    post = get_object_or_404(Post, slug=post,
                                   status='published',
                                   publish__year=year,
                                   publish__month=month,
                                   publish__day=day)    return render(request,                  'blog/post/detail.html',
                  {'post': post})

这是一个帖子详情视图(view)。这个视图(view)使用year,month,day以及post作为参数通过给予slug和日期来获取到一篇已经发布的帖子。请注意,当我们创建Post模型(model)的时候,我们给slgu字段添加了unique_for_date参数。这样我们可以确保在给予的日期中只有一个帖子会带有一个slug,因此,我们能通过日期和slug取回单独的帖子。在这个详情视图(view)中,我们通过使用get_object_or_404()快捷方法来检索期望的Post。这个函数能取回匹配给予的参数的对象,或者当没有匹配的对象时返回一个HTTP 404(Not found)异常。最后,我们使用render()快捷方法来使用一个模板(template)去渲染取回的帖子。

为你的视图(views)添加URL模式

一个URL模式是由一个Python正则表达,一个视图(view),一个全项目范围内的命名组成。Django在运行中会遍历所有URL模式直到第一个匹配的请求URL才停止。之后,Django导入匹配的URL模式中的视图(view)并执行它,使用关键字或指定参数来执行一个HttpRequest类的实例。
如果你之前没有接触过正则表达式,你需要去稍微了解下,通过访问 https://docs.python.org/3/howto/regex.html 。

在blog应用目录下创建一个urls.py文件,输入以下代码:

from django.conf.urls import urlfrom . import views
urlpatterns = [    # post views
    url(r'^$', views.post_list, name='post_list'),
    url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/'\
        r'(?P<post>[-\w]+)/$',
        views.post_detail,
        name='post_detail'),
]

第一条URL模式没有带入任何参数,它映射到post_list视图(view)。第二条URL模式带上了以下4个参数映射到post_detail视图(view)中。让我们看下这个URL模式中的正则表达式:

  • year:需要四位数

  • month:需要两位数。不及两位数,开头带上0,比如 01,02

  • day:需要两位数。不及两位数开头带上0

  • post:可以由单词和连字符组成

为每一个应用创建单独的urls.py文件是最好的方法,可以保证你的应用能给别的项目再度使用。

现在你需要将你blog中的URL模式包含到项目的主URL模式中。编辑你的项目中的mysite文件夹中的urls.py文件,如下所示:

from django.conf.urls import include, urlfrom django.contrib import admin

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)), 
    url(r'^blog/', include('blog.urls',
        namespace='blog',
        app_name='blog')),
]

通过这样的方式,你告诉Django在blog/路径下包含了blog应用中的urls.py定义的URL模式。你可以给它们一个命名空间叫做blog,这样你可以方便的引用这个URLs组。

模型(models)的标准URLs

你可以使用之前定义的post_detail URL给Post对象构建标准URL。Django的惯例是给模型(model)添加get_absolute_url()方法用来返回一个对象的标准URL。在这个方法中,我们使用reverse()方法允许你通过它们的名字和可选的参数来构建URLS。编辑你的models.py文件添加如下代码:

from django.core.urlresolvers import reverse
Class Post(models.Model):    # ...
    def get_absolute_url(self):
        return reverse('blog:post_detail',
                        args=[self.publish.year,                              self.publish.strftime('%m'),                              self.publish.strftime('%d'),                              self.slug])

请注意,我们通过使用strftime()方法来保证个位数的月份和日期需要带上0来构建URL(译者注:也就是01,02,03)。我们将会在我们的模板(templates)中使用get_absolute_url()方法。

为你的视图(views)创建模板(templates)

我们为我们的应用创建了视图(views)和URL模式。现在该添加模板(templates)来展示界面友好的帖子了。

在你的blog应用目录下创建以下目录结构和文件:

templates/
    blog/
        base.html
        post/            list.html
            detail.html

以上就是我们的模板(templates)的文件目录结构。base.html文件将会包含站点主要的HTML结构以及分割内容区域和一个导航栏。list.htmldetail.html文件会继承base.html文件来渲染各自的blog帖子列和详情视图(view)。

Django有一个强大的模板(templates)语言允许你指定数据的如何进行展示。它基于模板标签(templates tags), 例如 {% tag %}, {{ variable }}以及模板过滤器(templates filters),可以对变量进行过滤,例如 {{ variable|filter }}。你可以通过访问 https://docs.djangoproject.com/en/1.8/ ref/templates/builtins/ 找到所有的内置模板标签(templates tags)和过滤器(filters)。

让我们来编辑base.html文件并添加如下代码:

{% load staticfiles %}<!DOCTYPE html><html><head>
  <title>{% block title %}{% endblock %}</title>
  <link href="{% static "css/blog.css" %}" rel="stylesheet"></head><body>
  <div id="content">
    {% block content %}
    {% endblock %}  </div>
  <div id="sidebar">
    <h2>My blog</h2>
      <p>This is my blog.</p>
  </div></body></html>

你可以看到有两个{% block %}标签(tags)。这些是用来告诉Django我们想在这个区域中定义一个区块(block)。继承这个模板(template)的其他模板(templates)可以使用自定义的内容来填充区块(block)。我们定义了一个区块(block)叫做title,另一个区块(block)叫做content

让我们编辑post/list.html文件使它如下所示:

{% extends "blog/base.html" %}

{% block title %}My Blog{% endblock %}

{% block content %}  <h1>My Blog</h1>
  {% for post in posts %}    <h2>
      <a href="{{ post.get_absolute_url }}">
        {{ post.title }}      </a>
    </h2>
    <p class="date">
      Published {{ post.publish }} by {{ post.author }}    </p>
    {{ post.body|truncatewords:30|linebreaks }}
  {% endfor %}
{% endblock %}

通过{% extends %}模板标签(template tag),我们告诉Django需要继承blog/base.html 模板(template)。然后我们在titlecontent区块(blocks)中填充内容。我们通过循环迭代帖子来展示它们的标题,日期,作者和内容,在标题中还集成了帖子的标准URL链接。在帖子的内容中,我们应用了两个模板过滤器(template filters): truncatewords用来缩短内容限制在一定的字数内,linebreaks用来转换内容中的换行符为HTML的换行符。只要你喜欢你可以连接许多模板标签(tempalte filters),每一个都会应用到上个输出生成的结果上。

打开终端执行命令python manage.py runserver来启动开发服务器。在浏览器中打开 http://127.0.0.1:8000/blog/ 你会看到运行结果。注意,你需要添加一些发布状态的帖子才能在这儿看到它们。你会看到如下图所示:

这之后,让我们来编辑post/detail.html文件使它如下所示:

{% extends "blog/base.html" %}

{% block title %}{{ post.title }}{% endblock %}

{% block content %}  <h1>{{ post.title }}</h1>
  <p class="date">
    Published {{ post.publish }} by {{ post.author }}  </p>
  {{ post.body|linebreaks }}
{% endblock %}

现在,你可以在浏览器中点击其中一篇帖子的标题来看帖子的详细视图(view)。你会看到类似以下页面:

添加页码

当你开始给你的blog添加内容,你很快会意识到你需要将帖子分页显示。Django有一个内置的Paginator类允许你方便的管理分页。

编辑blog应用下的views.py文件导入Django的页码类修改post_list如下所示:

from django.core.paginator import Paginator, EmptyPage, PageNotAnIntegerdef post_list(request):
    object_list = Post.published.all()
    paginator = Paginator(object_list, 3) # 3 posts in each page
    page = request.GET.get('page')    try:
        posts = paginator.page(page)    except PageNotAnInteger:        # If page is not an integer deliver the first page
        posts = paginator.page(1)    except EmptyPage:        # If page is out of range deliver last page of results
        posts = paginator.page(paginator.num_pages)    return render(request,                  'blog/post/list.html',
                  {'page': page, 
                   'posts': posts})

Paginator是如何工作的:

  • 我们使用希望在每页中显示的对象的数量来实例化Paginator类。

  • 我们获取到page GET参数来指明页数

  • 我们通过调用Paginatorpage()方法在期望的页面中获得了对象。

  • 如果page参数不是一个整数,我们就返回第一页的结果。如果这个参数数字超出了最大的页数,我们就展示最后一页的结果。

  • 我们传递页数并且获取对象给这个模板(template)。

现在,我们必须创建一个模板(template)来展示分页处理,它可以被任意的模板(template)包含来使用分页。在blog应用的templates文件夹下创建一个新文件命名为pagination.html。在该文件中添加如下HTML代码:

<div class="pagination">
  <span class="step-links">
    {% if page.has_previous %}      <a href="?page={{ page.previous_page_number }}">Previous</a>
    {% endif %}    <span class="current">
      Page {{ page.number }} of {{ page.paginator.num_pages }}.    </span>
      {% if page.has_next %}        <a href="?page={{ page.next_page_number }}">Next</a>
      {% endif %}  </span></div>    

为了渲染上一页与下一页的链接并且展示当前页面和所有页面的结果,这个分页模板(template)期望一个Page对象。让我们回到blog/post/list.html模板(tempalte)中将pagination.html模板(template)包含在{% content %}区块(block)中,如下所示:

{% block content %}
  ...
  {% include "pagination.html" with page=posts %}
{% endblock %}

我们传递给模板(template)的Page对象叫做posts,我们将分页模板(tempalte)包含在帖子列模板(template)中指定参数来对它进行正确的渲染。这种方法你可以反复使用,用你的分页模板(template)对不同的模型(models)视图(views)进行分页处理。

现在,在你的浏览器中打开 http://127.0.0.1:8000/blog/。 你会看到帖子列的底部已经有分页处理:

使用基于类的视图(views)

因为一个视图(view)的调用就是得到一个web请求并且返回一个web响应,你可以将你的视图(views)定义成类方法。Django为此定义了基础的视图(view)类。它们都从View类继承而来,View类可以操控HTTP方法调度以及其他的功能。这是一个可替代的方法来创建你的视图(views)。

我们准备通过使用Django提供的通用ListView使我们的post_list视图(view)转变为一个基于类的视图。这个基础视图(view)允许你对任意的对象进行排列。

编辑你的blog应用下的views.py文件,如下所示:

from django.views.generic import ListViewclass PostListView(ListView):
    queryset = Post.published.all()
    context_object_name = 'posts'
    paginate_by = 3
    template_name = 'blog/post/list.html'

这个基于类的的视图(view)类似与之前的post_list视图(view)。在这儿,我们告诉ListView做了以下操作:

  • 使用一个特定的查询集(QuerySet)代替取回所有的对象。代替定义一个queryset属性,我们可以指定model = Post然后Django将会构建Post.objects.all() 查询集(QuerySet)给我们。

  • 使用环境变量posts给查询结果。如果我们不指定任意的context_object_name默认的变量将会是object_list

  • 对结果进行分页处理每页只显示3个对象。

  • 使用定制的模板(template)来渲染页面。如果我们不设置默认的模板(template),ListView将会使用blog/post_list.html

现在,打开你的blog应用下的urls.py文件,注释到之前的post_listURL模式,在之后添加一个新的URL模式来使用PostlistView类,如下所示:

urlpatterns = [    # post views
    # url(r'^$', views.post_list, name='post_list'),
    url(r'^$', views.PostListView.as_view(),name='post_list'),
    url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/'\
        r'(?P<post>[-\w]+)/$',
        views.post_detail,
        name='post_detail'),
]

为了保持分页处理能工作,我们必须将正确的页面对象传递给模板(tempalte)。Django的ListView通过叫做page_obj的变量来传递被选择的页面,所以你必须编辑你的post_list_html模板(template)去包含使用了正确的变量的分页处理,如下所示:

{% include "pagination.html" with page=page_obj %}

在你的浏览器中打开 http://127.0.0.1:8000/blog/ 然后检查每一样功能是否都和之前的post_list视图(view)一样工作。这是一个简单的,通过使用Django提供的通用类的基于类视图(view)的例子。你将在第十章,创建一个在线学习平台以及相关的章节中学到更多的基于类的视图(views)。

总结

在本章中,你通过创建一个基础的blog应用学习了Django web框架的基础。你为你的项目设计了数据模型(models)并且进行了数据库迁移。你为你的blog创建了视图(views),模板(templates)以及URLs,还包括对象分页。

在下一章中,你会学习到如何增强你的blog应用,例如评论系统,标签(tag)功能,并且允许你的用户通过邮件来分享帖子。


以上是关于django搭建个人博客的主要内容,如果未能解决你的问题,请参考以下文章

Django搭建个人博客平台2---创建一个Django项目和项目梳理

Django搭建个人博客平台2---创建一个Django项目和项目梳理

Django搭建个人博客平台6---前端templates模板index页

Django搭建个人博客平台6---前端templates模板index页

Django搭建个人博客平台3---博客表结构设计和markdown编辑器

Django搭建个人博客平台3---博客表结构设计和markdown编辑器