我们来通过自定义过滤器使我们的博客文章可以支持Markdown语法,然后将其转换成对应的HTML格式。Markdown是一种易于使用的轻型标记语言而且可以方便的转为HTML。可以在这里查看Markdown语法的详情:https://daringfireball.net/projects/markdown/basics。
先通过pip安装Python的Markdown模块:
pip install Markdown==2.6.11然后编辑blog_tags.py,添加如下内容:
from django.utils.safestring import mark_safe import markdown @register.filter(name=\'markdown\') def markdown_format(text): return mark_safe(markdown.markdown(text))我们使用和模板标签类似的方式注册了模板过滤器,为了不使我们的函数和markdown模块重名,将我们的函数命名为markdown_format,但是指定了模板中的标签名称为markdown,这样就可以通过{{ variable|markdown }}来使用标签了。mark_safe用来告诉Django该段HTML代码是安全的,可以将其渲染到最终页面中。默认情况下,Django对于生成的HTML代码都会进行转义而不会当成HTML代码解析,只有对mark_safe标记的内容才会正常解析,这是为了避免在页面中出现危险代码(如添加外部JavaScript文件的代码)。
然后在blog/post/list.html和blog/post/detail.html中的{% extends %}之后引入自定义模板的模块:
{% load blog_tags %}在post/detail.html中,找到下边这行:
{{ post.body|linebreaks }}将其替换成:
{{ post.body|markdown }}然后在post/list.html中,找到下边这行:
{{ post.body|truncatewords:30|linebreaks }}将其替换成:
{{ post.body|markdown|truncatewords_html:30 }}truncatewords_html过滤器不会截断未闭合的HTML标签。
浏览器中打开:8000/admin/blog/post/add/然后写一段使用Markdown语法的正文:
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/)然后在浏览器中查看刚添加的文章,可以看到如下的结果:
可以看到,自定义模板过滤器在需要自定义格式的时候非常好用。可在找到更多关于自定义过滤器的信息。
2创建站点地图Django带有站点地图功能框架,可以根据网站内容动态的生成站点地图。站点地图是一个XML文件,用于给搜索引擎提供信息,可以帮助搜索引擎爬虫索引站点的内容。
Django的站点地图框架是django.contrib.sites。如果使用同一个Django项目运行多个站点,站点地图功能允许为每个站点创建单独的站点地图。为了使用站点地图功能,需要启用django.contrib.sites和jango.contrib.sitemaps,将这两个应用添加到settings.py的INSTALLED_APPS设置中:
SITE_ID = 1 # Application definition INSTALLED_APPS = [ # ... \'django.contrib.sites\', \'django.contrib.sitemaps\', ]由于添加了新应用,需要执行数据迁移。迁移完成之后,在blog应用目录内创建sitemaps.py文件并添加如下代码:
from django.contrib.sitemaps import Sitemap from .models import Post class PostSitemap(Sitemap): changefreq = \'weekly\' priority = 0.9 def items(self): return Post.published.all() def lastmod(self, obj): return obj.updated我们通过继承django.contrib.sitemaps的Sitemap类创建了一个站点地图对象。changefreq和priority属性表示文章页面更新的频率和这些文章与站点的相关性(最大相关性为1)。使用items()方法返回这个站点地图所需的QuerySet,Django默认会调用数据对象的get_absolute_url()获取对应的URL,如果想手工指定具体的URL,可以为PostSitemap添加一个location方法。lastmod方法接收items()返回的每一个数据对象然后返回其更新时间。changefreq和priority可以通过定义方法也可以作为属性名进行设置。站点地图的详细使用可以看官方文档:https://docs.djangoproject.com/en/2.0/ref/contrib/sitemaps/。
最后就是配置站点地图对应的URL,打开项目的根urls.py,添加如下代码:
from django.urls import path, include from django.contrib import admin from django.contrib.sitemaps.views import sitemap from blog.sitemaps import PostSitemap sitemaps = {\'posts\': PostSitemap,} urlpatterns = [ path(\'admin/\', admin.site.urls), path(\'blog/\', include(\'blog.urls\', namespace=\'blog\')), path(\'sitemap.xml\', sitemap, {\'sitemaps\': sitemaps}, name=\'django.contrib.sitemaps.views.sitemap\') ]