1.6 构建列表和详细视图

  在了解如何使用ORM后,即可着手准备构建博客应用程序的视图.Django视图仅表示为一个python函数,接收Web请求并返回一个Web响应.另外,返回响应结果的全部逻辑均位于视图中.

  首先,需要创建应用程序视图,并于随后针对每个视图定义URL.最后,还需要创建HTML模板,以渲染视图所生成的数据.其中,每个视图将渲染一个模板(向其中传递变量),并返回包含渲染输出结果的HTTP响应.

 

  1.6.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视图接收request对象作为唯一参数.需要注意的是,全部视图都需要使用到该参数.在当前视图中,将利用之前创建的published管理器,检索包含published状态的所有帖子.

  最后,是使用Django提供的render()方法渲染包含给定模板的帖子列表.该函数接收request对象、模板路径以及上下文变量,进而渲染给定的模板.另外,该函数返回包含渲染文本(一般为HTML代码)的HttpResponse对象.render()快捷方式涉及请求上下文,因而模板上下文处理器设置的任意变量均可被给定的模板所访问.模板上下文处理器只是将变量设置到上下文中的可调用程序.

 

  下面创建第二个视图并显示独立的帖子.对此,可向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和日期的发布帖子.注意,当创建post模型时,将向slug字段加入unique_for_date参数.通过这一方式,对于既定日期,可确保仅存在一个包含slug的帖子.因此,可通过日期和slug检索单一帖子.在详细视图中,我们采用get_object_or_404()快捷方式检索期望的帖子.该函数检索与既定参数匹配的对象;或者,如果对象不存在,则抛出HTTP404异常.最后,使用render()快捷方式并通过模板渲染检索到的帖子.

 

  1.6.2 向视图添加URL路径

  URL路径可将URL映射至视图上,具体来说,URL路径由字符串路径、视图和可在项目范围内命名URL的名称(可选)组成.Django遍历每个URL路径,并在第一个请求URL匹配的路径处停止.随后,Django导入与URL路径匹配的视图并对其加以执行、传递HttpResponse类实例和关键字(或者位置参数).

  下面在blog应用程序目录的urls.py文件中添加下列代码行:

from django.conf.urls import url
from . import views
app_name = 'blog'
urlpatterns = [
  # post views url(r
'', views.post_list,name='post_list'), url(r'<int:year>/<int:month>/<int:day>/<slug:post>/', views.post_detail,name='post_detail'), ]

  上述代码中,通过app_name变量定义了应用程序命名空间,并可通过应用程序组织URL,并在引用时使用对应名称.这里通过path()函数定义了两种不同的路径.其中,第一个URL路径不接收任何参数,并映射至post_list视图.第二个路径接收下列4个参数,并映射至post_detail视图上.

  • year  表示为一个整数
  • month  表示为一个整数
  • day  表示为一个整数
  • post  由单词和连字符组成

  此处,我们使用尖括号捕捉URL值.任何定义URL路径中的值(形如<paramter>)均作为字符串被捕捉.我们将使用路径转换器(如<int:year>)以实现特定的匹配,并返回一个整数和<slug:post>,且与slug实现特定的匹配(由ASCII字母、数字、连字符和下划线构成的字符串.)

  如果url()和转换器无法满足当前要求,则可采用re_path()定义包含python正则表达式的复杂URL路径.

 

  针对每个应用程序创建urls.py文件可视为应用程序复用的一种最佳方式.

 

  目前,需要在项目的主URL路径中包含blog应用程序的URL路径.对此,可编辑位于项目my_project目录中的urls.py文件,如下所示:

from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^blog/', include('blog.urls',namespace='blog')),
]

  利用include定义的新URL路径引用了定义于blog应用程序中的URL路径,因而包含于blog/路径中.另外,此类路径还位于命名空间blog中.此外,命名空间须在整个项目中保持唯一.我们即可方便地引用blogURL,如blog:post_list和blog:post_detail.

 

  1.6.3 模型的标准URL

  我们可以使用1.6.2节定义的post_detail URL针对Post对象构建标准URL.在Django中,对应规则可描述为:向返回对象的标准URL的模型中添加get_absolute_url()方法.针对该方法,我们将使用reserve()方法,并可通过对应的名称和所传递的可选参数构建URL.对此,可编辑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()方法,进而链接至特定的帖子.

posted @ 2019-08-26 09:35  周亚澄  阅读(186)  评论(0编辑  收藏  举报