本文主要是介绍Django开发--step4 详情界面url的获取,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在我们开发的博客系统中,每一篇博客的连接都是不同的,比如第一篇博客的url /post/1 第二篇是/post/2
一、设置文章详细页的URL
在urlpatterns上添加一句 app_name=‘blog'
这句话的作用是告诉Django这个urls.py模块时属于blogapp这个应用的
在blogapp/urls.py中添加
url(r'^post/(?P<pk>[0-9]+)/$', views.detail, name='detail'),
(?P<pk>[0-9]+)表示命名捕获组,作用是把用户访问的url里吧括号内匹配的字符串捕获作为关键字参数传给其对应的视图函数detail
在上述这个正则表达式中,匹配的数字会在detail视图函数被调用时进行传递,实际的视图函数
detail(request, pk=255)
为了方便生成上述的URL 我们在Post类中定义一个get_absolute_url方法
# 自定义 get_absolute_url 方法, 加载Post类的最后# 记得从 django.urls 中导入 reverse 函数def get_absolute_url(self):return reverse('blog:detail', kwargs={'pk': self.pk})
关于reverse函数
reverse
函数,它的第一个参数的值是'blog:detail'
,意思是 blog 应用下的name=detail
的函数,由于我们在上面通过app_name = 'blog'
告诉了 Django 这个 URL 模块是属于 blog 应用的,因此 Django 能够顺利地找到 blog 应用下 name 为 detail 的视图函数,于是reverse
函数会去解析这个视图函数对应的 URL,我们这里 detail 对应的规则就是post/(?P<pk>[0-9]+)/
这个正则表达式,而正则表达式部分会被后面传入的参数pk
替换,所以,如果Post
的 id(或者 pk,这里 pk 和 id 是等价的) 是 255 的话,那么get_absolute_url
函数返回的就是 /post/255/ ,这样 Post 自己就生成了自己的 URL。
二、编写视图函数
关于detail的视图函数
def detail(request, pk):post = get_object_or_404(Post, pk=pk)return render(request, 'blog/detail.html', context={'post': post})
pk与文章的id是等价的,从 django.shortcuts 模块导入的 get_object_or_404
方法,其作用就是当传入的 pk 对应的 Post 在数据库存在时,就返回对应的 post
,如果不存在,就给用户返回一个 404 错误,表明用户请求的文章不存在。
三、模板继承
在templates下创建base.html
由于在index和detail中,只有main标签内内容是不同的,所有我们可以把相同的部分抽取出来,复制index.html 中的内容到base.html中在 main 标签处,删掉main标签中之前的内容
...
<main class="col-md-8">{% block main %}{% endblock main %}
</main>
<aside class="col-md-4">{% block toc %}{% endblock toc %}...
</aside>
...
其中,block也是模板标签,作用是占位,该block的名字是main
然后在index.html中,我们就可以删去之前的东西,在最顶部加入
{% extends 'base.html' %}
来继承base.html
另外在 {% block main %}{% endblock main %} 包裹的地方填上 index 页面应该显示的内容:
{% extends 'base.html' %}{% block main %}{% for post in post_list %}<article class="post post-1">...</article>{% empty %}<div class="no-post">暂时还没有发布的文章!</div>{% endfor %}
{% endblock main %}
四、Markdown与代码高亮
Markdown 是一种 HTML 文本标记语言,只要遵循它约定的语法格式,Markdown 的渲染器就能够把我们写的文章转换为标准的 HTML 文档,从而让我们的文章呈现更加丰富的格式,例如标题、列表、代码块等等 HTML 元素。
安装Python Markdown
激活虚拟环境,使用命令 :pip install markdown
然后,对 post
的 body
的值做一下渲染,把 Markdown 文本转为 HTML 文本再传递给模板:在视图函数中
import markdown
from django.shortcuts import render, get_object_or_404
from .models import Postdef 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})
注意这里我们给 markdown
渲染函数传递了额外的参数 extensions
,它是对 Markdown 语法的拓展,这里我们使用了三个拓展,分别是 extra、codehilite、toc。extra 本身包含很多拓展,而 codehilite 是语法高亮拓展,这为我们后面的实现代码高亮功能提供基础,而 toc 则允许我们自动生成目录。
在文章中插入图片,目前能做的且推荐做的是使用外链引入图片。比如将图片上传到七牛云这样的云存储服务器,然后通过 Markdown 的图片语法将图片引入。Markdown 引入图片的语法为:
。
当前查看效果,页面中并没有像我们预期的那样,而全是HTML标签,接下来,我们加入过滤器
关于safe标签:
Django 出于安全方面的考虑,任何的 HTML 代码在 Django 的模板中都会被转义(即显示原始的 HTML 代码,而不是经浏览器渲染后的格式)。为了解除转义,只需在模板标签使用 safe
过滤器即可,告诉 Django,这段文本是安全的,在模板中找到展示博客文章主体的 {{ post.body }} 部分,为其加上 safe 过滤器,{{ post.body|safe }},大功告成。
代码高亮
安装Pygmants 激活虚拟环境 运行 pip install Pygments安装即可
然后在base.html中,引入
<link rel="stylesheet" href="{% static 'blog/css/highlights/github.css' %}">
就可以了
测试代码高亮与Markdown的代码
# 一级标题## 二级标题### 三级标题~~~{.python}
def detail():return 'like'
~~~
```python
@requires_authorization
def somefunc(param1='', param2=0):'''A docstring'''if param1 > param2: # interestingprint 'Greater'return (param2 - param1 + 1) or Noneclass SomeClass:pass>>> message = '''interpreter
... prompt'''
```JavaScript 示例:``` javascript
/**
* nth element in the fibonacci series.
* @param n >= 0
* @return the nth element, >= 0.
*/
function fib(n) {var a = 1, b = 1;var tmp;while (--n >= 0) {tmp = a;a += b;b = tmp;}return a;
}document.write(fib(10));
```- 列表项1
- 列表项2
- 列表项3> 这是一段引用
五、使用自定义模板标签
在页面中,有“最新文章”这个展示区
自己定义一个模板标签,例如名为 get_recent_posts
的模板标签,它可以这样工作:我们只要在模板中写入 {% get_recent_posts as recent_post_list %},那么模板中就会有一个从数据库获取的最新文章列表,并通过 as 语句保存到 recent_post_list
模板变量里。这样我们就可以通过 {% for %} {% endfor%} 模板标签来循环这个变量,显示最新文章列表了,这和我们在编写博客首页面视图函数是类似的。首页视图函数中从数据库获取文章列表并保存到 post_list
变量,然后把这个 post_list
变量传给模板,模板使用 for 模板标签循环这个文章列表变量,从而展示一篇篇文章。这里唯一的不同是我们从数据库获取文章列表的操作不是在视图函数中进行,而是在模板中通过自定义的 {% get_recent_posts %} 模板标签进行。当然,自定义标签需要符合Django的规范。
在blogapp下创建一个templatetags文件夹,然后在这个文件夹下创建一个__init__.py
之后再在当前目录下创建一个blog_tags.py的文件夹
模板标签本质上还是Python函数
最终 blog_app.py的代码是:
from django import template
from ..models import Post, Categoryregister = template.Library() # 实例化的template.Library类# 最新文章模板标签 num代表获取前num篇
# 将函数装饰为register.simple_tag,这样就可以在模板中使用{% get_recent_posts %}调用这个函数了
@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():return Category.objects.all()
自定义模板标签的使用:
首先在base.html中加入
{% load blog_tags %}
最新文章处
<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>
分类与归档处,也进行同样结构的修改
<h3 class="widget-title">分类</h3>{% get_categories as category_list %}<ul>{% for category in category_list%}<li><a href="#">{{ category.name }}<span class="post-count">(13)</span></a></li>{% empty %}暂无分类{% endfor %}</ul>
就可以了
这篇关于Django开发--step4 详情界面url的获取的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!