18年7月3号,按照
Django 博客开发教程目录索引(全 26 )https://www.jianshu.com/p/a822b479106a
搭建部署了博客,从中学习到了很多。
记录一些新学习到的django知识。
def detail(request, pk): post = get_object_or_404(Post, pk=pk) return render(request, 'blog/detail.html', context={'post': post})
class Post(models.Model): ... def __str__(self): return self.title # 自定义 get_absolute_url 方法 # 记得从 django.urls 中导入 reverse 函数 def get_absolute_url(self): return reverse('blog:detail', kwargs={'pk': self.pk})
这个 reverse
函数,它的第一个参数的值是 'blog:detail'
,意思是 blog 应用下的 name=detail
的函数,由于我们在上面通过 app_name = 'blog'
告诉了 Django 这个 URL 模块是属于 blog 应用的,因此 Django 能够顺利地找到 blog 应用下 name 为 detail 的视图函数,由于 get_absolute_url 这个方法(我们定义在 Post 类中的)返回的是 post
对应的 URL,因此这里 {{ post.get_absolute_url }} 最终会被替换成该 post
自身的 URL。url.py要加上
app_name = 'blog' urlpatterns = [ url(r'^$', views.index, name='index'), url(r'^post/(?P<pk>[0-9]+)/$', views.detail, name='detail'), ]
django2.0可以改成
path('post/<int:pk>', views.detail, name='detail')
--------------------------------------------
支持 Markdown 语法和代码高亮
pip install markdown
blog/views.py import markdown from django.shortcuts import render, get_object_or_404 from .models import Post def detail(request, pk): post = get_object_or_404(Post, pk=pk) # 记得在顶部引入 markdown 模块 post.body = markdown.markdown(post.body, extensions=[ 'markdown.extensions.extra', 'markdown.extensions.codehilite', 'markdown.extensions.toc', ]) return render(request, 'blog/detail.html', context={'post': post})
简单的用法
# 一级标题 ## 二级标题 ### 三级标题 - 列表项1 - 列表项2 - 列表项3 > 这是一段引用 ```python def detail(request, pk): post = get_object_or_404(Post, pk=pk) post.body = markdown.markdown(post.body, extensions=[ 'markdown.extensions.extra', 'markdown.extensions.codehilite', 'markdown.extensions.toc', ]) return render(request, 'blog/detail.html', context={'post': post}) ```
safe 标签
我们在发布的文章详情页没有看到预期的效果,而是类似于一堆乱码一样的 HTML 标签,这些标签本应该在浏览器显示它本身的格式,但是 Django 出于安全方面的考虑,任何的 HTML 代码在 Django 的模板中都会被转义(即显示原始的 HTML 代码,而不是经浏览器渲染后的格式)。为了解除转义,只需在模板标签使用 safe
过滤器即可,告诉 Django,这段文本是安全的,你什么也不用做。在模板中找到展示博客文章主体的 {{ post.body }} 部分,为其加上 safe 过滤器,{{ post.body|safe }},大功告成,这下看到预期效果了。
safe 是 Django 模板系统中的过滤器(Filter),可以简单地把它看成是一种函数,其作用是作用于模板变量,将模板变量的值变为经过滤器处理过后的值。例如这里 {{ post.body|safe }},本来 {{ post.body }} 经模板系统渲染后应该显示 body 本身的值,但是在后面加上 safe 过滤器后,渲染的值不再是body 本身的值,而是由 safe 函数处理后返回的值。过滤器的用法是在模板变量后加一个 | 管道符号,再加上过滤器的名称。可以连续使用多个过滤器,例如 {{ var|filter1|filter2 }}。
安装 Pygments
运行: pip install Pygments
安装即可。
Markdown 使用 Pygments 在后台为我们做了很多事
<link rel="stylesheet" href="{% static 'blog/css/highlights/github.css' %}"> #引入样式文件
使用自定义模板标签
blog/templatetags/blog_tags.py from django import template from ..models import Post register = template.Library() @register.simple_tag def get_recent_posts(num=5): return Post.objects.all().order_by('-created_time')[:num]
@register.simple_tag
def archives():
return Post.objects.dates('created_time', 'month', order='DESC')
@register.simple_tag
def get_categories():
# 别忘了在顶部引入 Category 类
return Category.objects.all()
这里我们首先导入 template 这个模块,然后实例化了一个 template.Library
类,并将函数 get_recent_posts
装饰为 register.simple_tag
。这样就可以在模板中使用语法 {% get_recent_posts %} 调用这个函数了。
templates/base.html <div class="widget widget-recent-posts"> <h3 class="widget-title">最新文章</h3> {% get_recent_posts as recent_post_list %} <ul> {% for post in recent_post_list %} <li> <a href="{{ post.get_absolute_url }}">{{ post.title }}</a> </li> {% empty %} 暂无文章! {% endfor %} </ul> </div>