现在你已经知道如何去使用 ORM了。你要准备为 blog
应用程序创建一个视图了。Django 视图知识一个 接受 web 请求 并返回 web 响应的 python 函数。返回所需response的所有逻辑都在视图内部。
首先,你将创建应用程序视图,然后为每一个视图定义一个 URL 模式,最后,您将创建 HTML 模板来呈现视图生成的数据。每个视图将呈现一个模板,然后将变量传递给它,并将返回一个带有呈现输出的HTTP响应。
1. 创建 列表 和 详情 视图
让我们来创建一个视图来显示帖子列表。编辑 blog
应用程序的 views.py
文件,使它看起来像这样:
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_list(request):
posts = Post.published.all()
return render(request,
'blog/post/list.html',
{'posts': posts})
你创建了你的第一个 Django 视图。post_list
视图将请求对象作为唯一参数,所有的视图都需要这个参数。在这个视图中,你使用以前定义的 published
管理器根据 published
的状态去得到所有的文章。
最后, 使用Django提供的render()
快捷方式用给定的模板呈现文章列表,这个函数接受一个 requests
对象,模板路径和上下文变量来呈现给定的模板,它返回带有呈现文本的 HttpResponse
对象,通常是HTML代码。render()
快捷方式考虑了请求上下文,因此模板上下文处理器的设置的任何变量都可以被给定模板访问。模板上下文处理器只是将变量设置到上下文中的可调用函数。你将在第三章 扩展你的 blog 应用程序 中学到更多。
让我们创建第二个视图去展示单一的文章。 添加下面这个函数到 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})
这是 文章详情视图,这个视图接受 year
, month
, day
, post
参数 通过给定 的 slug 和 date 去查询一个已经发布文章。注意,在创建 Post
模型的时候,你在 slug
字段中添加了一个 unique_for_date
参数。这确保了对于给定的日期,只有一个带有 slug
的文章,因此,你可以使用 date 和 slug 去检索到唯一的 文章。在 详情视图中,你使用 get_object_or_404()
快捷方式去得到想要文章。这个函数匹配给定的参数返回一个对象,如果没有找到对象,则返回一个 HTTP 404(未找到) 异常。最后你可以使用 render()
快捷方式 使用一个模板渲染 得到的文章。
2. 为你的视图添加 路由模式
路由模式允许你把一个 URL 映射到 视图中,一个 路由模式由 字符串模式,视图 和可选的名称组成,该名称允许您在项目范围内命名 URL。Django 遍历每一个模式,并在第一个与请求URL 匹配的模式上停止。然后 Django 导入匹配的URL模式的视图并执行它,并给它传递 HttpRequest
类的实例和关键字或位置参数。
在 blog
应用程序目录中创建 urls.py
文件中,并在其中添加下面的代码:
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
# 文章视图
path('', views.post_list, name='post_list'),
path('<int:year>/<int:month>/<int:day>/<slug:post>/', views.post_detail, name='post_detail')
]
在上面的代码里面,你通过 app_name
变量 定义了一个 应用程序的命令空间。 这运行你在应用程序中组织 URL, 并且在应用它的时候使用名字。你使用 path()
方法定义了两个不同的模式。这第一个 URL 模式不接受任何参数,并映射到 post_list
视图中。这第二个模式在后面接受四个参数,并且映射到 post_detail
视图中:
-
year
: 需要一个整数 -
month
: 需要一个整数 -
day
: 需要一个整数 -
post
: 可以由单词和超链接组成。
你使用尖括号从 URL 中捕获值。URL模式中指定为任何值都被<parameter>
捕获为字符串,你使用 路径 转换器,例如 <int: year>
, 来指定匹配并返回一个整数,<slug:post>
来指定匹配一个 slug。你可以通过Django 这个链接,来看看所有的 路径转化器。
如果使用 path()
和 转换器对您还不够充分的化,你可以用 re_path()
来替代,通过 Python 正则表达式来定义复杂的 URL 模式。 你可以在这个链接学习到 更多通过 正则表达式来定义 URL 模式的知识。如果你以前还没有使用过正则表达式,那么你先在这个如何操作正则表达式里面看看。
为每一个应用程序创建一个
urls.py
文件 是让你的应用程序在其他项目中变得可重用的最好办法。
接下来,你需要把blog
应用程序的路由模式添加到项目的主路由模式里面。
编辑在你mysite
项目本地目录中的 urls.py
文件,使其看起来像下面这样:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls', namespace='blog')),
]
使用 include
修改的新 URL模式 引用在博客应用程序中修改的 URL 模式,以便将他们包含在 blog/
路径下。将这些模式包含在 blog
的命名空间中。命名空间在项目中必须是唯一的。之后,你可以很容易的通过使用命名空间跟冒号和url的名称去引用 blog 的 ruls。例如:blog:post_list
和 blog:post_detail
。 你可以在这个链接中学习到更多有关 URL 名称空间的知识。
3. 规范的模型url
规范url 是 资源的首选 URL。你可以在站点中使用不同的页面来显示文章,但是只有一个 URL 作为 博客文章的 主 URL。Django 约定中在模型里面添加一个 get_absolute_url()
方法来将一个对象 转化成规范的 URL。
可以使用在上一节中定义的post_detail
URL为Post
对象构建规范URL,为了这个方法,你将要使用 reverse()
方法,它允许通过使用它们的名字和参数去构建一个 URLS。 你能在这个链接学习到更多有关 URL 功能函数的知识。
编辑 blog
应用程序中的 models.py
文件,并且添加下面的代码:
from django.urls import reverse
class Post(models.Model):
# ... 之前的代码 不要删除
def get_absolute_url(self):
return reverse('blog:post_detail',
args=[self.publish.year,self.publish.month, self.publish.day, self.slug])
你将在模板中使用 get_absolute_url()
方法链接到指定的文章。
网友评论