django项目实例精解(4)扩展博客应用程序

第三章内容:

  1. 创建自定义模板标签和过滤器,
  2. 添加网站地图和帖子提要,
  3. 利用PostgreSQL实现全文本搜索。
    我自己补充点内容:
    之前博客一直没有样式,侧边栏也没正确显示,我自己搜了下,来完成这个。当然依旧不会很好看。在项目settings.py 中加入:
STATICFILES_DIRS = [(os.path.join(BASE_DIR, 'static'))]

然后新建static文件夹,下面建css文件夹新建文件blog.css,写入:

#content{float: left;width:800px;height: 150px;}
#sidebar{border-left: 1px solid #e1e1e1;float: right;width: 384px;}

3.1 创建自定义模板标签和过滤器

创建templatetags文件,添加__init__.py,再建blog_tags.py,填写代码:

from django import template
from ..models import Post

register = template.Library()

@register.simple_tag  # 注册为简单的标签
def total_posts():
    return Post.published.count()
    

在blog/templates/base.html中添加:
一个在上面,一个在下面,自己调整位置。

{% load blog_tags %}
<p>This is my blog.I've written {% total_posts %} posts so far.</p>

可以运行项目查看一下,
在blog_tags.py写下列代码:

@register.inclusion_tag('blog/post/latest_posts.html')
def show_latest_posts(count=5):
    latest_posts = Post.published.order_by('-publish')[:count]
    return {'latest_posts': latest_posts} 

然后再blog/post/latest_posts.html写代码:

<ul>
    {% for post in latest_posts %}
    <li>
        <a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
    </li>
    {% endfor %}
</ul>

侧栏base.html:

<h3>Latest posts</h3>
    {% show_latest_posts 3 %}

在blog_tags.py写下列代码:

@register.simple_tag
def get_most_commented_posts(count=5):
    return Post.published.annotate(
        total_comments=Count('comments')
    ).order_by('-total_comments')[:count]

侧栏base.html下面加入:

<h3>Most commented posts</h3>
    {% get_most_commented_posts as most_commented_posts %}
    <ul>
        {% for post in most_commented_posts %}
        <li>
            <a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
        </li>
        {% endfor %}
    </ul>

在这里插入图片描述
django 包含了各种内建模板过滤器,并可调整模板中的变量。
这里我们创建一个自定义过滤器,使用markdown语法,将帖子内容转化为html.

pip install Markdown==2.6.11

在blog_tags.py文件中加入代码:

import markdown
from django.utils.safestring import mark_safe

@register.filter(name='markdown')
def markdown_format(text):
    return mark_safe(markdown.markdown(text))

在blog/post/list.html和blog/post/detail.html中extend下面加这个:

{% load blog_tags %}

detail.html中上面那个修改为下面的:

<!--{{ post.body|linebreaks }}-->
{{ post.body|markdown }}

list.html中上面那个修改为下面的:

<!--{{ post.body|truncatewords:30|linebreaks }}-->
{{ post.body|markdown|truncatewords:30| }}

在浏览器输入http://127.0.0.1:8000/admin/blog/post/add/添加下面内容

This is a post formatted with markdown
---------------------------------------------

*This is emphasized* and **this is more emphasized**.

Here is a list:

*One
*Two
*Three

And a [link to the Django website](https://www.djangoproject.com/)

打开博客页面可以看到显示方式有了变化。

3.2 向站点添加网站地图

dango 中包含了网站地图框架,进而可动态生成网站地图。
编辑主项目settings.py文件:

SITE_ID = 1

INSTALLED_APPS = [
    ...
    'django.contrib.sites',
    'django.contrib.sitemaps',
]

执行迁移

python manage.py migrate

sites应用程序将与数据库同步,在blog文件夹下创建sitemaps.py,添加代码:

from django.contrib.sitemaps import Sitemap
from blog.models import Post

class PostSitemap(Sitemap):  # 继承Sitemap生成自定义网站地图
    changefreq = 'weekly'  # 页面变化频率
    priority = 0.9

    def items(self):  # 网站地图对象的QuerySet
        return Post.published.all()

    def lastmod(self, obj):  # 检索items()返回的各个对象,返回最近修改时间
        return obj.updated

配置主项目的urls.py,这里我贴出完整的代码:

from django.contrib import admin
from django.contrib.sitemaps.views import sitemap
from django.urls import path, include

from sitemaps import PostSitemap

sitemaps = {
    'posts': PostSitemap,
}

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include(('blog.urls', 'blog'), namespace='blog')),
    path('sitemap.xml/', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'),
]

访问:http://127.0.0.1:8000/sitemap.xml/

AttributeError at /sitemap.xml/
'Post' object has no attribute 'updated'

我的这里报错了,不知道怎么解决,大佬知道的话,告诉我下,我先把那个注释掉:

#def lastmod(self, obj):  # 检索items()返回的各个对象,返回最近修改时间
        #return obj.updated

3.3 创建帖子提要

django 包含了一个内建聚合提要(feed)框架,可据此动态生成RSS或Atom提要。
title,link,description对应RSS元素。
blog下创建feeds.py文件添加下列代码:

from django.contrib.syndication.views import Feed
from django.template.defaultfilters import truncatewords

from blog.models import Post


class LatestPostsFeed(Feed):
    title = 'My blog'
    link = '/blog/'
    description = 'New posts of my blog.'
    
    def items(self):
        return Post.published.all()[:5]
    
    def item_title(self, item):  # 获取条目标题
        return item.title
    
    def item_description(self, item):  # 获取条目描述
    #使用truncatewords内建模板过滤器构建博客帖子的描述内容(30个单词)。
        return truncatewords(item.body, 30)

访问http://127.0.0.1:8000/blog/feed/可以看到下面内容。
在这里插入图片描述

发布了48 篇原创文章 · 获赞 0 · 访问量 732

猜你喜欢

转载自blog.csdn.net/qq_36710311/article/details/104778879