快速上手:为模型添加 SEO 元数据

本文以一个已有的 Django 博客 Article 模型为例,分三步为它加上完整的 SEO 元数据。开始之前,请先完成安装。


第 1 步:给模型加上 SeoModelMixin

# blog/models.py

from django.db import models
from seo_suite.mixins import SeoModelMixin


class Article(SeoModelMixin, models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    slug = models.SlugField(unique=True)
    published = models.BooleanField(default=False)

    def get_absolute_url(self):
        return f"/articles/{self.slug}/"

模型只需改这一处。不新增字段,也不需要迁移。

SeoModelMixin 按 约定的字段名 从模型已有字段中读取元数据:

元数据字段 依次尝试的模型字段
title title、name、headline
meta_description meta_description、description、summary、excerpt
meta_keywords meta_keywords、keywords
og_image og_image、image、cover_image、photo、thumbnail
canonical_url get_absolute_url() 的返回值

如果你的字段名不在其中,可以用 SEO_FIELD_MAP 告诉 mixin 去哪里取值,详见博客文章。


第 2 步:给详情视图加上 SeoViewMixin

# blog/views.py

from django.views.generic import DetailView
from seo_suite.mixins import SeoViewMixin

from .models import Article


class ArticleDetail(SeoViewMixin, DetailView):
    model = Article
    template_name = "blog/article_detail.html"
    slug_field = "slug"
    slug_url_kwarg = "slug"

SeoViewMixin 会把视图的上下文对象(self.object)接入解析器:自动调用该对象的 get_seo_metadata(),并把得到的 FinalizedSeoMetadata 以 seo 为名放入模板上下文。


第 3 步:在基础模板中加入 {% seo_head %}

如果安装时已经在基础模板里加过 {% seo_head %},这一步可以跳过。如果你用的是单页模板:

{# blog/templates/blog/article_detail.html #}
{% extends "base.html" %}
{% load seo_suite %}

{% block extra_head %}
  {% seo_head %}
{% endblock %}

也可以放在所有页面共用的基础模板中:

{# templates/base.html #}
{% load seo_suite %}
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  {% seo_head %}
</head>
<body>
  {% block content %}{% endblock %}
</body>
</html>

渲染结果

假设有一篇 Article,其 title="How Django Routing Works"、description="A deep dive into URL resolvers."、slug="how-django-routing-works",站点运行在 https://example.com,那么 <head> 中会渲染出:

<title>How Django Routing Works</title>
<meta name="description" content="A deep dive into URL resolvers.">
<meta name="robots" content="index,follow">
<link rel="canonical" href="https://example.com/articles/how-django-routing-works/">
<meta property="og:type" content="website">
<meta property="og:title" content="How Django Routing Works">
<meta property="og:description" content="A deep dive into URL resolvers.">
<meta property="og:url" content="https://example.com/articles/how-django-routing-works/">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="How Django Routing Works">
<meta name="twitter:description" content="A deep dive into URL resolvers.">

几点说明:

  • og:title 和 og:description 直接取自页面标题和描述,无需额外代码。
  • og:url 与 canonical URL 保持一致。
  • twitter:card 在没有图片时默认为 "summary",有图片时变为 "summary_large_image"。
  • robots: index,follow 来自 SEO_SUITE["DEFAULTS"] 中的全局默认值。你可以按页面或在全站范围内修改,参见全站默认值。

添加标题后缀

要给全站标题加上类似 " | My Blog" 的后缀,只需一项设置:

# settings.py

SEO_SUITE = {
    "DEFAULTS": {
        "title_suffix": " | My Blog",
        "robots": "index,follow",
    },
}

此时 <title> 标签渲染为:

<title>How Django Routing Works | My Blog</title>

下一步