指南:详情视图¶
在 DetailView 上混入 SeoViewMixin,默认即可得到从对象派生的元数据,
同时也能在视图层面方便地覆盖特定字段。
默认行为¶
把 SeoViewMixin 混入 DetailView 后,解析器会同时拿到视图和 self.object。
对象的 get_seo_metadata() 以优先级 40 运行;视图上的任何 seo_* 属性或
get_seo_metadata() 覆盖则以优先级 50 运行。
from django.views.generic import DetailView
from seo_suite.mixins import SeoViewMixin
from .models import Article
class ArticleDetail(SeoViewMixin, DetailView):
model = Article
slug_field = "slug"
slug_url_kwarg = "slug"
这就够了。文章的 title、description、canonical URL,以及 SeoModelMixin
解析出的其他字段都会自动使用。
覆盖单个字段¶
设置 seo_* 类属性即可覆盖特定字段,无需改动模型:
class ArticleDetail(SeoViewMixin, DetailView):
model = Article
slug_field = "slug"
seo_robots = "noindex" # drafts, paywalled content, etc.
可用的类属性如下(默认值均为 None,表示“不表态”):
| 属性 | 元数据字段 |
|---|---|
seo_title |
title |
seo_title_suffix |
title_suffix |
seo_h1 |
h1 |
seo_description |
meta_description |
seo_keywords |
meta_keywords |
seo_robots |
robots |
seo_canonical |
canonical_url |
seo_og_image |
og_image |
用 get_seo_metadata 动态覆盖¶
如果取值取决于请求状态,重写 get_seo_metadata:
class ArticleDetail(SeoViewMixin, DetailView):
model = Article
def get_seo_metadata(self, context=None):
from seo_suite.metadata import SeoMetadata
# Only suppress indexing for unpublished content.
if not self.object.published:
return SeoMetadata.partial(robots="noindex,nofollow")
# Return UNSET for all fields to defer entirely to the object layer.
return SeoMetadata.partial()
SeoMetadata.partial(**kwargs) 构造的元数据对象只设置指定的字段,其余字段
保持 UNSET,由优先级更低的层提供。
视图标题覆盖对象,canonical 保留¶
一种常见做法:视图设置带品牌的标题,同时保留对象的 canonical URL:
class ArticleDetail(SeoViewMixin, DetailView):
model = Article
seo_title = "Read Our Latest" # overrides article.title at priority 50
# canonical_url is not set here, so article.get_absolute_url() survives
视图上的 seo_canonical 为 None(不表态),因此对象由 get_absolute_url()
得到的 canonical_url 会原样使用。
在视图层面添加 JSON-LD¶
用 seo_schema_profiles 在视图层面启用 schema 配置。当配置取决于请求上下文时
(例如只在首页添加 WebSite 配置),这很有用:
模型和视图都声明了配置时,两组 JSON-LD 块都会输出(累加规则)。 参见 JSON-LD 结构化数据。
不配合 DetailView 使用 SeoViewMixin¶
SeoViewMixin 可以配合任何带有 get_context_data 的基于类的视图使用。
object 属性是可选的;如果存在,会传给解析器。
from django.views.generic.base import View
from django.shortcuts import get_object_or_404
from seo_suite.mixins import SeoViewMixin
from seo_suite.context import attach_seo
class MyCustomView(SeoViewMixin, View):
seo_title = "Custom Page"
def get(self, request, pk):
self.object = get_object_or_404(Article, pk=pk)
seo = attach_seo(request, view=self, obj=self.object)
# ... render response ...